I am trying to use atob for converting base64 encoded data to string. I found its working fine in Mozilla and Chrome, but it is not working in IE. Please tell me any substitue for this, or how to make this work in IE
Go to this link and include js present there:
http://code.google.com/p/stringencoders/source/browse/trunk/javascript/base64.js?r=230
/*
* Copyright (c) 2010 Nick Galbreath
* See full license on http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript
*/
var base64 = {};
base64.PADCHAR = '=';
base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
base64.makeDOMException = function() {
// sadly in FF,Safari,Chrome you can't make a DOMException
var e, tmp;
try {
return new DOMException(DOMException.INVALID_CHARACTER_ERR);
} catch (tmp) {
// not available, just passback a duck-typed equiv
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype
var ex = new Error("DOM Exception 5");
// ex.number and ex.description is IE-specific.
ex.code = ex.number = 5;
ex.name = ex.description = "INVALID_CHARACTER_ERR";
// Safari/Chrome output format
ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; };
return ex;
}
}
base64.getbyte64 = function(s,i) {
// This is oddly fast, except on Chrome/V8.
// Minimal or no improvement in performance by using a
// object with properties mapping chars to value (eg. 'A': 0)
var idx = base64.ALPHA.indexOf(s.charAt(i));
if (idx === -1) {
throw base64.makeDOMException();
}
return idx;
}
base64.decode = function(s) {
// convert to string
s = '' + s;
var getbyte64 = base64.getbyte64;
var pads, i, b10;
var imax = s.length
if (imax === 0) {
return s;
}
if (imax % 4 !== 0) {
throw base64.makeDOMException();
}
pads = 0
if (s.charAt(imax - 1) === base64.PADCHAR) {
pads = 1;
if (s.charAt(imax - 2) === base64.PADCHAR) {
pads = 2;
}
// either way, we want to ignore this last block
imax -= 4;
}
var x = [];
for (i = 0; i < imax; i += 4) {
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) |
(getbyte64(s,i+2) << 6) | getbyte64(s,i+3);
x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff));
}
switch (pads) {
case 1:
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6);
x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff));
break;
case 2:
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12);
x.push(String.fromCharCode(b10 >> 16));
break;
}
return x.join('');
}
base64.getbyte = function(s,i) {
var x = s.charCodeAt(i);
if (x > 255) {
throw base64.makeDOMException();
}
return x;
}
base64.encode = function(s) {
if (arguments.length !== 1) {
throw new SyntaxError("Not enough arguments");
}
var padchar = base64.PADCHAR;
var alpha = base64.ALPHA;
var getbyte = base64.getbyte;
var i, b10;
var x = [];
// convert to string
s = '' + s;
var imax = s.length - s.length % 3;
if (s.length === 0) {
return s;
}
for (i = 0; i < imax; i += 3) {
b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2);
x.push(alpha.charAt(b10 >> 18));
x.push(alpha.charAt((b10 >> 12) & 0x3F));
x.push(alpha.charAt((b10 >> 6) & 0x3f));
x.push(alpha.charAt(b10 & 0x3f));
}
switch (s.length - imax) {
case 1:
b10 = getbyte(s,i) << 16;
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
padchar + padchar);
break;
case 2:
b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8);
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
alpha.charAt((b10 >> 6) & 0x3f) + padchar);
break;
}
return x.join('');
}
atob and btoa are mozilla specific functions afterwards the support was extended to webkit browser like chrome,safari so it doesn't work in IE.
So better use some other functions like :-
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
this will resolve your problem
Related
I'm trying to create a IWICBitmap from an EXR file (error checks removed).
#pragma pack(push,1)
struct fl
{
float r, g, b, a;
};
#pragma pack(pop)
HRESULT Open(const char* f,IWICBitmap** d)
{
exr_context_initializer_t ctxtinit = EXR_DEFAULT_CONTEXT_INITIALIZER;
exr_context_t myfile = {};
exr_result_t rv = exr_start_read(&myfile, f, &ctxtinit);
int part_index = 0;
const exr_attr_chlist_t* chl = 0;
exr_get_channels(myfile, part_index, &chl);
int32_t ck = 0;
rv = exr_get_chunk_count(myfile, part_index, &ck);
int32_t sl = 0;
rv = exr_get_scanlines_per_chunk(myfile, part_index, &sl);
int y = 0;
int wi = 0;
int he = 0;
std::vector<fl> data; // put here the floats
exr_decode_pipeline_t dec = {};
for (int32_t cuk = 0; cuk < ck; cuk++)
{
exr_chunk_info_t ch = {};
exr_read_scanline_chunk_info(myfile, part_index, y, &ch);
wi = ch.width;
he += ch.height;
y += sl;
bool first = 0;
if (dec.decompress_fn == 0)
{
rv = exr_decoding_initialize(myfile, part_index, &ch, &dec);
rv = exr_decoding_choose_default_routines(myfile, part_index, &dec);
first = 1;
}
if (!first)
rv = exr_decoding_update(myfile, part_index,&ch,&dec);
rv = exr_decoding_run(myfile, part_index, &dec);
int NumPixels = (wi * ch.height);
auto BytesPerPixel = ch.unpacked_size / NumPixels;
if (true)
{
// RGB(A)
if (chl->entries[0].pixel_type == EXR_PIXEL_HALF)
{
if (BytesPerPixel == chl->num_channels * 2)
{
auto ds = data.size();
data.resize(ds + NumPixels);
auto p = data.data() + ds;
char* x = (char*)dec.unpacked_buffer;
for (int j = 0; j < NumPixels; j++)
{
uint16_t* u = (uint16_t*)x;
p->a = 1.0f;
for (int jH = 0; jH < chl->num_channels; jH++)
{
half ha(Imath_3_2::half::FromBits,*u);
ha.setBits(*u);
if (strcmp(chl->entries[jH].name.str, "R") == 0) p->r = ha.operator float();
if (strcmp(chl->entries[jH].name.str, "G") == 0) p->g = ha.operator float();
if (strcmp(chl->entries[jH].name.str, "B") == 0) p->b = ha.operator float();
if (strcmp(chl->entries[jH].name.str, "A") == 0) p->a = ha.operator float();
u++;
}
x += BytesPerPixel;
p++;
}
}
else
break;
}
if (chl->entries[0].pixel_type == EXR_PIXEL_FLOAT)
{
// code removed for simplicity, I guess the same issue happens here unless it's a problem of the half-float
}
}
}
rv = exr_decoding_destroy(myfile, &dec);
exr_finish(&myfile);
CComPtr<IWICImagingFactory2> wbfact = 0;
CoCreateInstance(CLSID_WICImagingFactory2, 0, CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory2), (void**)&wbfact);
return wbfact->CreateBitmapFromMemory(wi, he, GUID_WICPixelFormat128bppPRGBAFloat, wi * 16,(UINT)data.size()*16, (BYTE*)data.data(), d);
}
What am I doing wrong? The pixel number I'm reading is correct (in this image 800x800).
My result:
Photoshop:
Is there a problem with the half-float? I'm just using the OpenEXR's IMath implementation.
im studying Algorithm with Javascript.
It is a problem abt dijkstra algorith.
but i always meet TLE(Time Limit Exceeded) in the last case.
could i know which point makes my code slower.
i tried many ways like below
without function constructor
console output with forEach
take input with require('readline')
without recursive heapify
it is the problem link.
https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/12/ALDS1_12_C
It is my solution.
function MinPQ() {
this.heap = [];
}
MinPQ.prototype.swap = function (i, j) {
const temp = this.heap[i];
this.heap[i] = this.heap[j];
this.heap[j] = temp;
};
MinPQ.prototype.insert = function (n) {
const parentIdx = (idx) => Math.floor((idx - 1) * 0.5);
this.heap.push(n);
let curr = this.heap.length - 1;
let parent = parentIdx(curr);
while (curr > 0 && this.compare(curr, parent)) {
this.swap(curr, parent);
curr = parent;
parent = parentIdx(curr);
}
};
MinPQ.prototype.shift = function () {
const heapify = (idx) => {
let l = idx * 2 + 1;
let r = idx * 2 + 2;
let minIdx = idx;
if (l < this.heap.length && this.compare(l, minIdx)) {
minIdx = l;
}
if (r < this.heap.length && this.compare(r, minIdx)) {
minIdx = r;
}
if (minIdx !== idx) {
this.swap(idx, minIdx);
heapify(minIdx);
}
};
this.swap(0, this.heap.length - 1);
const root = this.heap.pop();
heapify(0);
return root;
};
MinPQ.prototype.compare = function (i, j) {
return this.heap[i][1] < this.heap[j][1];
};
function solution(input) {
const n = Number(input.shift());
const G = Array(n);
for (let i = 0; i < n; i++) {
const [u, k, ...adjs] = input.shift().split(' ').map(Number);
G[u] = [];
for (let j = 0; j < k; j++) {
const v = adjs[2 * j];
const c = adjs[2 * j + 1];
G[u][v] = c;
}
}
return dijkstra(n, G)
.map((e, idx) => `${idx} ${e}`)
.join('\n');
}
function dijkstra(n, G) {
const minPQ = new MinPQ();
const d = Array(n).fill(Infinity);
let count = 0;
minPQ.insert([0, 0]);
while (count < n) {
const node = minPQ.shift();
const [u, cost] = node;
if (d[u] < Infinity) continue;
d[u] = cost;
count++;
G[u].forEach((e, idx) => {
minPQ.insert([idx, cost + e]);
});
}
return d;
}
(function (test) {
const printSolution = (input) => console.log(solution(input));
if (test) {
printSolution([
'5',
'0 3 2 3 3 1 1 2',
'1 2 0 2 3 4',
'2 3 0 3 3 1 4 1',
'3 4 2 1 0 1 1 4 4 3',
'4 2 2 1 3 3',
]);
console.log('--');
printSolution([
'9',
'0 2 1 1 3 13',
'1 3 0 1 2 1 4 11',
'2 2 5 1 1 1',
'3 3 4 1 0 13 6 1',
'4 4 1 11 5 1 3 1 7 4',
'5 3 2 1 8 7 4 1',
'6 2 3 1 7 1',
'7 3 4 4 6 1 8 1',
'8 2 5 7 7 1',
]);
return;
}
printSolution(
require('fs').readFileSync('/dev/stdin', 'utf-8').split('\n')
);
})(0);
It is the solution what passed last case.
var h = [],hs = 0;
h[0] = new Array(2);
h[0][0] = -1;h[0][1] = -1;
function insert(key){
h[++hs] = key;
var i = hs;
while(h[i][1] < h[Math.floor(i / 2)][1]){
var ex = h[i];
h[i] = h[Math.floor(i / 2)];
h[Math.floor(i / 2)] = ex;
i = Math.floor(i / 2);
}
}
function extract(){
if(hs <= 0)
return;
var ret = h[1];
h[1] = h[hs--];
i = 1;
while((i * 2 <= hs && h[i][1] > h[i * 2][1]) || (i * 2 + 1 <= hs && h[i][1] > h[i * 2 + 1][1])){
var l = i * 2;var r = i * 2;
if(i * 2 + 1 <= hs)
r++;
var m = h[l][1] <= h[r][1] ? l : r;
var ex = h[i];
h[i] = h[m];
h[m] = ex;
i = m;
}
return ret;
}
function Main(input){
input = input.split("\n");
var n = parseInt(input[0],10);
var graph = new Array(n);
for(var i = 0;i < n;i++){
input[i + 1] = input[i + 1].split(" ");
var u = parseInt(input[i + 1][0],10);
var k = parseInt(input[i + 1][1],10);
graph[u] = new Array(k);
for(var j = 0;j < k;j++)
graph[u][j] = new Array(2);
for(var j = 0;j < k;j++){
graph[u][j][0] = parseInt(input[i + 1][j * 2 + 2],10);
graph[u][j][1] = parseInt(input[i + 1][j * 2 + 3],10);
}
}
var count = 1;
var sum = Array(n);
for(var i = 0;i < n;i++)
sum[i] = 1000000000;
sum[0] = 0;
for(var i = 0;i < graph[0].length;i++){
insert(graph[0][i]);
}
while(count < n){
var aa = extract();
if(sum[aa[0]] < 1000000000)
continue;
sum[aa[0]] = aa[1];
count++;
for(var i = 0;i < graph[aa[0]].length;i++){
graph[aa[0]][i][1] += sum[aa[0]];
insert(graph[aa[0]][i]);
}
}
for(var i = 0;i < n;i++){
console.log(i + " " + sum[i]);
}
}
Main(require("fs").readFileSync("/dev/stdin","utf8"));
Something like this, having a field in the document and hashing it (md5 for example) to generate the _id:
PUT index/doc/1?pretty
{
"name": "foo",
"_id": "hash(doc['name'])"
}
Yes, you can do that using an ingest pipeline.
First, let's define a pipeline with a script processor that will compute your _id field. Since Painless doesn't provide any hashing method, the one below is a Painless implementation of SHA1, but you can substitute that by any other hashing algorithm of your choosing
PUT _ingest/pipeline/id-generator
{
"description" : "This pipeline generates an ID based on the SHA1 hash of the name field",
"processors" : [
{
"script": {
"lang": "painless",
"source": """
def hex(int num) {
def hex_chr = "0123456789abcdef".toCharArray();
String str = "";
for(int j = 7; j >= 0; j--)
str += hex_chr[((num >> (j * 4)) & 15)];
return str;
}
def str2blks_SHA1(String str){
int nblk = ((str.length() + 8) >> 6) + 1;
int[] blks = new int[nblk * 16];
for(int a = 0; a < nblk * 16; a++)
blks[a] = 0;int i = 0;
for(; i < str.length(); i++)
blks[i >> 2] |= str.codePointAt(i) << (24 - (i % 4) * 8);
blks[i >> 2] |= 128 << (24 - (i % 4) * 8);
blks[nblk * 16 - 1] = str.length() * 8;
return blks;
}
def add(def x, def y){
def lsw = (x & 65535) + (y & 65535);
def msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 65535);
}
def rol(def num, def cnt){
return (num << cnt) | (num >>> (32 - cnt));
}
def ft(def t, def b, def c, def d){
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
def kt(def t){
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514;
}
def calcSHA1(def str){
def x = str2blks_SHA1(str);
def w = new def[80];
def a = 1732584193;
def b = -271733879;
def c = -1732584194;
def d = 271733878;
def e = -1009589776;
for(def i = 0; i < x.length; i = i + 16){
def olda = a;
def oldb = b;
def oldc = c;
def oldd = d;
def olde = e;
for(def j = 0; j < 80; j++){
if(j < 16) {
w[j] = x[i + j];
} else {
w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
}
def t = add(add(rol(a, 5), ft(j, b, c, d)), add(add(e, w[j]), kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = add(a, olda);
b = add(b, oldb);
c = add(c, oldc);
d = add(d, oldd);
e = add(e, olde);
}
return hex(a) + hex(b) + hex(c) + hex(d) + hex(e);
}
ctx._id = calcSHA1(ctx.name);
"""
}
}
]
}
Then you can simply index your document by referencing the pipeline like this:
POST myindex/_doc?pipeline=id-generator
{
"name": "John Doe"
}
Result:
{
"_index": "myindex",
"_type": "_doc",
"_id": "ae6e4d1209f17b460503904fad297b31e9cf6362",
"_score": 1,
"_source": {
"name": "John Doe"
}
}
I'm trying to create a program to hide data in a image file. Data bits are hidden into last bit of every pixels blue value. First four pixels contain the length of following data bytes.
Everything works fine when I encrypt the data to image and then decrypt it without saving the image in between. However if I encrypt the data to an image and then save it and then open the file again and try to decrypt it, decryption fails since the values seem to have changed.
I wonder if there is something similar happening as with txt files where there is BOM containing byte order data prepended into the file?
The code works if I change the color c = crypted.pixels[pos + i];
to color c = original.pixels[pos + i]; in readByteAt function
and run the encrypting function first and then the decryption function.
This causes the code to run the decryption function on the just encrypted image still in program memory instead reading it from the file.
Any ideas on what causes this or how to prevent it are welcome!
here is the full (messy) code:
PImage original;
PImage crypted;
int imagesize;
boolean ready = false;
void setup() {
size(100, 100);
imagesize = width * height;
}
void draw() {
}
void encrypt()
{
original = loadImage("image.jpg");
original.loadPixels();
println("begin encrypt");
int pos = 0;
byte b[] = loadBytes("DATA.txt");
println("encrypting in image...");
int len = b.length;
println("len " + len);
writeByteAt((len >> (3*8)) & 0xFF, 0);
writeByteAt((len >> (2*8)) & 0xFF, 8);
writeByteAt((len >> (1*8)) & 0xFF, 16);
writeByteAt(len & 0xFF, 24);
pos = 32;
for (int i = 3; i < b.length; i++) {
int a = b[i] & 0xff;
print(char(a));
writeByteAt(a, pos);
pos += 8;
}
original.updatePixels();
println();
println("done");
original.save("encrypted.jpg");
}
void writeByteAt(int b, int pos)
{
println("writing " + b + " at " + pos);
for (int i = 0; i < 8; i++)
{
color c = original.pixels[pos + i];
int v = int(blue(c));
if ((b & (1 << i)) > 0)
{
v = v | 1;
} else
{
v = v & 0xFE;
}
original.pixels[pos+i] = color(red(c), green(c), v);
//original.pixels[pos+i] = color(255,255,255);
}
}
int readByteAt(int pos)
{
int b = 0;
for (int i = 0; i < 8; i++)
{
color c = crypted.pixels[pos + i];
int v = int(blue(c));
if ((v & 1) > 0)
{
b += (1 << i);
}
}
return b;
}
void decrypt()
{
crypted = loadImage("encrypted.jpg");
crypted.loadPixels();
println("begin decrypt");
int pos = 0;
PrintWriter output = createWriter("out.txt");
println("decrypting...");
int len = 0;
len += readByteAt(0) << 3*8;
len += readByteAt(8) << 2*8;
len += readByteAt(16) << 1*8;
len += readByteAt(24);
pos = 32;
if(len >= imagesize)
{
println("ERROR: DATA LENGTH OVER IMAGE SIZE");
return;
}
println(len);
while (pos < ((len+1)*8)) {
output.print(char(readByteAt(pos)));
print(char(readByteAt(pos)));
pos += 8;
}
output.flush(); // Writes the remaining data to the file
output.close();
println("\nDone");
}
void keyPressed()
{
if(key == 'e')
{
encrypt();
}
if(key == 'd')
{
decrypt();
}
}
I need to convert the user enter amount into words. For example, 1230.30 into one thousand two hundered and thirty rupees thirty paise.So,how to convert it?
public string NumberToText(int number)
{
if (number == 0) return "Zero";
if (number == -2147483648) return "Minus Two Hundred and Fourteen Crore Seventy Four Lakh Eighty Three Thousand Six Hundred and Forty Eight";
int[] num = new int[4];
int first = 0;
int u, h, t;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
if (number < 0)
{
sb.Append("Minus ");
number = -number;
}
string[] words0 = {"" ,"One ", "Two ", "Three ", "Four ",
"Five " ,"Six ", "Seven ", "Eight ", "Nine "};
string[] words1 = {"Ten ", "Eleven ", "Twelve ", "Thirteen ", "Fourteen ",
"Fifteen ","Sixteen ","Seventeen ","Eighteen ", "Nineteen "};
string[] words2 = {"Twenty ", "Thirty ", "Forty ", "Fifty ", "Sixty ",
"Seventy ","Eighty ", "Ninety "};
string[] words3 = {"Thousand ", "Lakh ","Crore "};
num[0] = number % 1000; // units
num[1] = number / 1000;
num[2] = number / 100000;
num[1] = num[1] - 100 * num[2]; // thousands
num[3] = number / 10000000; // crores
num[2] = num[2] - 100 * num[3]; // lakhs
for(int i = 3; i > 0 ; i--)
{
if (num[i] != 0)
{
first = i;
break;
}
}
for(int i = first ; i >= 0 ; i--)
{
if (num[i] == 0) continue;
u = num[i] % 10; // ones
t = num[i] / 10;
h = num[i] / 100; // hundreds
t = t - 10 * h; // tens
if (h > 0) sb.Append(words0[h] + "Hundred ");
if (u > 0 || t > 0)
{
if (h > 0 || i == 0) sb.Append("and ");
if (t == 0)
sb.Append(words0[u]);
else if (t == 1)
sb.Append(words1[u]);
else
sb.Append(words2[t-2] + words0[u]);
}
if (i != 0) sb.Append(words3[i-1]);
}
return sb.ToString().TrimEnd();
}