-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathEnDe.js
4749 lines (4487 loc) · 181 KB
/
EnDe.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* ========================================================================= //
// vi: ts=4:
// vim: ts=4:
#?
#? NAME
#? EnDe.js
#?
#? SYNOPSIS
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="EnDe.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="aes.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="des.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="crc.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="md4.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="md5.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="rmd.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="sha.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="sha512.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="blowfish.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="EnDeB64.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="EnDeMaps.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="EnDeIP.js"></SCRIPT>
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="EnDeTS.js"></SCRIPT>
#?
#? Additional for testing:
#? <SCRIPT language="JavaScript1.5" type="text/javascript" src="EnDeTest.js"></SCRIPT>
#?
#? Additional user defined functions:
#? <SCRIPT language="JavaScript1.3" type="text/javascript" src="EnDeUser.js"></SCRIPT>
#?
#? DESCRIPTION
#? Functions for encoding, decoding and converting from and to plain text.
#? Functions for various timestamp and IP conversions.
#?
#? SEE ALSO
#? crc.js, aes.js, md4.js, md5.js, sha.js, sha512.js, rmd.js, blowfish.js
#? des.js, EnDeB64.js, EnDeMaps.js, EnDeUser.js, EnDeTest.js
#?
#? HACKER's INFO
# // ToDo: character maps:
# 1. define a new data structure which distinguishes characters sets
# from encoded characters (which is cureently mixed: see CP-1252)
# a) one table for characters and their encodings
# b) one table for character sets (ASCII, EBCDIC, Mac OS, ...)
# then implemt this.cp(), this.a2e(), this.e2a() in a new general
# function: this.c2c(from,to,src)
#? Special tags:
#? //#? some text
#? The special tag //#? is used for a short description text. It
#? must appear right after the function definition line. The text
#? following the tag is used as description of the function.
#? This tag is used in some generation scripts and Makefile.
#? Example:
#?
#? this.myfunc = function(parameter) {
#? //#? example description text
#? ...
#?
#? would extract "example description text". The text following
#? the tag must not contain any single or double quote.
#? NOTE that each function definition should be followed by such
#? tag, otherwise some generated code is syntactically incomplete.
#?
#? //#name? value: some text
#? The special tag //#name? is used for a short description text
#? of the same function with the parameter 'name' set to 'value'.
#? This tag is used in some generation scripts and Makefile.
#
# Function Parameters
# All functions which also have a public interface, for example used in
# the library/API, must use special names for their parameters. I.g. the
# function definition should look like:
# function ( type, mode, uppercase, src, prefix, suffix, delimiter )
# where all parameters are optional (any can be missing or be named _n1_
# .. _n7_; see below).
# This strict naming convention is necessary so that some generators are
# able to identify them. All public interfaces of the functions will be
# exported to EnDeFunc.txt (see Makefile for details). EnDeFunc.txt then
# is used by the GUI to build menus in the Functions window. The menus
# in the Functions window, when selected, then passes the generated text
# to the dispatcher functions: EnDe.FF.update() and EnDe.setObj() .
# Unused function parameters used to be named _na_ but due to complains
# of some JS-lint and/or packer programs they have been renamed to _n1_,
# _n2_, _n3_, _n4_, _n5_, _n6_, and _n7_ .
#?
#? VERSION
#? @(#) EnDe.js 3.50 14/11/08 12:40:16
#?
#? AUTHOR
#? 07-apr-07 Achim Hoffmann, mailto: EnDe (at) my (dash) stp (dot) net
#?
* ========================================================================= */
// ========================================================================= //
// Encoding, Decoding functions //
// ========================================================================= //
var EnDe = new function() {
this.SID = '3.50';
this.sid = function() { return('@(#) EnDe.js 3.50 14/11/08 12:40:16 EnDe'); };
// ===================================================================== //
// debug functions //
// ===================================================================== //
this.trace = 0;
this.dbx = function(src,nl) {
//#? wrapper for EnDeGUI.dpr()
if(this.trace<=0) { return false; }
if(EnDeGUI.dpr===undefined) {
/*
*** implement your code for debugging used in lib without GUI here ***
*/
return false;
}
return EnDeGUI.dpr(src,nl);
}; // EnDe.dbx
this.spr = function(src,nl) {
//#? wrapper for EnDeGUI.spr()
if(this.trace<=0) { return false; }
if(EnDeGUI.spr===undefined) { return false; }
return EnDeGUI.spr(src,nl);
}; // EnDe.spr
// ===================================================================== //
// wrapper functions //
// ===================================================================== //
this.encode = function(type,mode,uppercase,src,prefix,suffix,delimiter) { this.EN.dispatch(type,mode,uppercase,src,prefix,suffix,delimiter); };
//#? wrapper for EnDe.EN.dispatch()
this.decode = function(type,mode,uppercase,src,prefix,suffix,delimiter) { this.DE.dispatch(type,mode,uppercase,src,prefix,suffix,delimiter); };
//#? wrapper for EnDe.DE.dispatch()
this.convert= function(type,mode,uppercase,src,prefix,suffix,delimiter) { this.IP.dispatch(type,mode,uppercase,src,prefix,suffix,delimiter); };
//#? wrapper for EnDe.IP.dispatch()
this.alert = function(func,txt) {
//#? internal wrapper for alert()
// this is the internal function used for delivering messages to the user
// ** needs to be adapted to the environment where EnDe object is used **
alert('##' + func + ': ' + txt);
}; // alert
// ===================================================================== //
// global constants //
// ===================================================================== //
this.CONST = new function() { // ====== wrapper object for constants
this.sid = function() { return(EnDe.sid() + '.CONST'); };
this.___ = '___________________________________________________ ';
this.CHR = new function() { // ====== object for character constants
this.sid = function() { return(EnDe.CONST.sid() + '.CHR'); };
this.DIGITS = '0123456789'; // [0-9]
this.LC = 'abcdefghijklmnopqrstuvwxyz'; // [a-z]
this.UC = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // [A-Z]
this.binhex = '!"#$%&' + "'" + '()*+,- 012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr'; // RFC1741
this.hex = this.DIGITS + 'abcdefABCDEF'; // [0-9a-fA-F]
// this.hex = this.b10 + 'abcdef'; // [0-9a-f]
/* above not used 'cause some browsers are too stupid for
* str.match(/this.b10/, 'i')
* (namely Safari 3.x and Webkit), see this.isHex()
*/
this.alnum = this.DIGITS + this.LC + this.UC;
this.dq = '"';
this.uuPad = '`';
this.uuAnf = 'begin 664, filename\n';
this.uuEnd = '====\n';
this.uuEndH = 'end\n';
this.uuCount= 'M';
this.urlReg = /[a-zA-Z0-9\$\_\.\+\!\*\~\(\)\,\&\/\:\;\=\?\@\#\'\-]/;
this.meta = '!"$%&/()=?`{}[]+#*,.;:<>|-_~@\'\\';
this.lang = '\xc4\xe4\xd6\xf6\xdc\xfc\xdf\xe1\xe2\xe3\xe5\xe6\xe7\xe0\xe9\xea\xe8\xe3\xed\xef\xec\xf4\xf2\xfa\xfb\xfc\xf9\xfd\xf1\xf0\xf3\xf5\xf6\xf7\xf8\xfe\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdd\xde'; // ToDo: not yet complete ..
}; // .CONST.CHR
this.INT = new function() { // ====== object for integer constants
this.sid = function() { return(EnDe.CONST.sid() + '.INT'); };
this.lng = 4294967296; // 2^32
this.exp32 = this.lng;
this.exp31 = 2147483648; // 2^31
this.MAX31 = this.exp31 - 1; // 2^31-1
this.exp64 = 18446744073709551616; // 2^64 // becomes string in JavaScript!
this.exp63 = 9223372036854775808; // 2^63 // becomes string in JavaScript!
this.MAX63 = this.exp63 - 1; // 2^63-1 // becomes string in JavaScript!
this.exp53 = 9007199254740992; // 2^53 // becomes string in JavaScript!
this.MAX53 = this.exp53 - 1; // 2^53-1
}; // .CONST.INT
this.CST = new function() { // ====== object for miscelaneous constants
this.sid = function() { return(EnDe.CONST.sid() + '.CST'); };
this.teaDelta = 0x9E3779B9;
this.yencMagic = 42;
this.yencShift = 64;
this.blocksize = 120; // initial array size used in str2bytes()
/* blocksize is used when adding data to arrays
* empiric tests showed that an array size of 120 performce best when data
* is > 5k bytes
* str2bytes() converted a 80k string to an array in
* - roughly 2 hours without using blocksize
* - 20 seconds with blocksize=120
* - 30 seconds with blocksize=500
* - 45 seconds with blocksize=1020
*/
}; // .CONST.CST
this.ESC = new function() { // ====== object for escape character lists
this.JS = '\'"';
this.SQL = "'";
this.Quote = '\'"';
/* all following need to be done programatically
this.Java = '';
this.HTML = '';
this.CSS = '()[]{}\'";'; // but all other non 7-bit ASCII need to be \XX
this.URL = '';
this.XML = '';
*/
}; // .CONST.ESC
}; // EnDe.CONST
// ===================================================================== //
// global variables //
// ===================================================================== //
this.maxloop= 99999; // used to avoid time consuming loops
/* Some loops force the browser to show an alert window or even crashes
* the browser. To avoid this, some computations are limited to this size.
*/
// index to array of each intMap[n], dupMap[n], a2eMap[n], e2aMap[n], ucsMap[n], etc.
this.mapInt = 0; // integer value (unicode base) of character
this.mapStd = 1; // standard
this.mapChr = 1; // charcter itself (a2eMap, e2aMap)
this.mapDsc = 2; // description of charcter (a2eMap, e2aMap)
this.mapEty = 2; // entity name
this.mapSet = 3; // ISO character set
this.mapTxt = 4; // description
// ===================================================================== //
// global arrays; see EnDeMaps.js for initialisation //
// ===================================================================== //
this.pairs = new Array(22); // array to map characters used as pairs
this.pairs['('] = ')';
this.pairs['['] = ']';
this.pairs['{'] = '}';
this.pairs[')'] = '(';
this.pairs[']'] = '[';
this.pairs['}'] = '{';
this.pairs['<'] = '>';
this.pairs['>'] = '<';
this.pairs['"'] = '"';
this.pairs["'"] = "'";
this.pairs['/'] = '/';
this.pairs['|'] = '|';
this.pairs[':'] = ':';
this.pairs[','] = ',';
this.pairs[';'] = ';';
this.pairs['#'] = '#';
this.pairs['%'] = '%';
this.pairs['$'] = '$';
this.pairs['!'] = '!';
this.pairs['='] = '=';
/* Sizes in following Array definition are rather a guess
* JavaScript is clever enough to expand them as needed.
*/
// HTML Entity Name
this.intMap = new Array(256*256);// array of [standard, Entity, Group, Description]
this.ncrMap = new Array(); // array of char codes
this.ucsMap = new Array();
this.dupMap = new Array();
this.xmlMap = new Array(); // XML entities
this.winMap = new Array(); // for CP-1252 codings
this.winfMap = new Array(); // for CP-1252 codings
// other characters
this.figsMap = new Array(); // Baudot figures
this.ltrsMap = new Array(); // Baudot letters
this.AbrMap = new Array(); // ASCII Braille
this.DbrMap = new Array(); // Dotless Braille
this.NbrMap = new Array(); // NumBRL Braille
this.DadMap = new Array(); // Dada Urka
this.BladeMap = new Array(16); // Blade font
this.sosMap = new Array(50); // Morse characters
this.osoMap = new Array(50); // reverse Morse characters
this.asciiMap = new Array(256); // ASCII characters
this.DIN66003Map= new Array(256); // DIN 66003 characters (aka ISO 646)
this.DIN66003fMap= new Array(256); // reverse DIN66003Map
this.ebcdicMap = new Array(256); // EBCDIC characters
this.ebcdicUTF = new Array(256); // UTF-EBCDIC characters
this.romanMap = new Array(256); // Mac OS Roman characters
this.a2rMap = new Array(256); // [ASCII] = Mac OS Roman
this.r2aMap = new Array(256); // [Mac OS Roman] = ASCII
this.a2eMap = new Array(256); // [ASCII] = EBCDIC
this.e2aMap = new Array(256); // [EBCDIC] = ASCII
this.u2superMap = new Array(256); // Unicode = Unicode superscript characters
this.super2uMap = new Array(256); // Unicode superscript = Unicode characters
this.u2subMap = new Array(256); // Unicode = Unicode subscript characters
this.sub2uMap = new Array(256); // Unicode subscript = Unicode characters
this.spaceMap = new Array(50); // all Unicode space characters
this.dnaMap = new Array(256); // DNA/DNS (genetic) codes
this.mg0Map = new Array(20); // (MathGuard) 3x5 matrix for digits; variuant 0
this.mg1Map = new Array(20); // (MathGuard) 3x5 matrix for digits; variuant 1
this.gm0Map = new Array(20); // reverse 3x5 matrix for digits; variuant 0
this.gm1Map = new Array(20); // reverse 3x5 matrix for digits; variuant 1
/*
this.uhwMap = new Array(256); // map with Unicode halfwidth characters
*/
this.rangeMap = new Array(256); // Unicode code point ranges // ToDo: not yet used
// Base64 characters
this.b64Char = new Array(64); // [CharCode] = Char
this.b64Code = new Array(64); // [Char] = CharCode
this.b64AdditionalChars = new Array();
// ===================================================================== //
// global functions //
// ===================================================================== //
this.rex = function(src) {
//#? escape meta characters for RegExp
return src.replace(/[\$\&\#\%\.\^\?\*\+\[\]\{\}\(\)\\]/gi,function(c){return '\\'+c;});
}; // ENDe.rex
this.isBin = function(src) { return src.match('[^01]') ===null ? true : false; };
//#? return true if string consist of 0 and 1 characters only
this.isOct = function(src) { return src.match('[^0-7]')===null ? true : false; };
//#? return true if string consist of octal characters only
this.isInt = function(src) { return src.match('[^0-9]')===null ? true : false; };
//#? return true if string consist of dezimal characters only
this.isHex = function(src) { return src.match('[^' + this.CONST.CHR.hex + ']')===null ? true : false; };
//#? return true if string consist of hex characters only
this.isB16 = function(src) { return EnDe.B64.isB16(src); };
//#? return true if string consist of Base16 characters only
this.isB32 = function(src) { return EnDe.B64.isB32(src); };
//#? return true if string consist of Base32 characters only
this.isB64 = function(src) { return EnDe.B64.isB64(src); };
//#? return true if string consist of Base64 characters only
this.isU64 = function(src) { return EnDe.B64.isU64(src); };
//#? return true if string consist of Url64 characters only
this.isalnum= function(src) { return src.match('[^' + this.CONST.CHR.alnum+ ']')===null ? true : false; };
//#? return true if string consist of alpha-numeric characters only
this.isTyp = function(type,src) {
//#? return true if string is of given type
switch (type) {
case 'bin': return EnDe.isBin(src); break;
case 'oct': return EnDe.isOct(src); break;
case 'dez': return EnDe.isInt(src); break;
case 'int': return EnDe.isInt(src); break;
case 'hex': return EnDe.isHex(src); break;
case 'b32':
case 'b64':
case 'u64': return EnDe.B64.is(type, src); break;
default :
if (/^base/.test(type)===true) {
return EnDe.B64.is(type, src); break;
}
break;
}
return false;
// ToDo: using if instead of switch would improve performance
}; // EnDe.isTyp
// ===================================================================== //
// global text utility functions //
// ===================================================================== //
this.join = function(type,mode,_n3_,src,prefix,suffix,delimiter) {
//#? global replace newlinw or tab character
//#type? apex: global replace newline by :
//#type? arg: global replace newline by &
//#type? dwr: global replace newline by newline (do nothing)
//#type? gwt: global replace newline by |
//#type? key: global replace tabs by =
//#type? list: global replace tabs by ,
//#type? del: global replace newline by given delimiter
var rex = /\n/;
var ccc = '';
switch (type) {
case 'apex': rex = /\n/g; ccc = ':'; break;
case 'arg': rex = /\n/g; ccc = '&'; break;
case 'gwt': rex = /\n/g; ccc = '|'; break;
case 'key': rex = /\t/g; ccc = '='; break;
case 'list': rex = /\t/g; ccc = ','; break;
case 'del': rex = /\n/g; ccc = delimiter; break;
case 'dwr': return src; break;
}
var bux = src.replace(rex,ccc);
rex = null;
return bux;
}; // EnDe.join
this.split = function(type,mode,_n3_,src,prefix,suffix,delimiter) {
//#? global split
//#type? apex: global split, replace : by newline
//#type? arg: global split, replace & by newline
//#type? gwt: global split, replace | by newline
//#type? key: global split, replace = by tabs
//#type? list: global split, replace , by tabs
//#type? del: global split, replace given delimiter
//#type? dwr: global split, replace newline by newline (do nothing)
var rex = null;
var ccc = '';
switch (type) {
case 'apex': ccc = '\n'; rex = new RegExp(':','g'); break;
case 'arg': ccc = '\n'; rex = new RegExp('&','g'); break;
case 'gwt': ccc = '\n'; rex = new RegExp('[|]','g'); break;
case 'key': ccc = '\t'; rex = new RegExp('=','g'); break;
case 'list': ccc = '\t'; rex = new RegExp(',','g'); break;
case 'del': ccc = '\n'; rex = new RegExp(delimiter,'g'); break;
case 'dwr': return src; break;
default : ccc = ''; rex = new RegExp('&=','g'); break;
}
var bux = src.replace(rex,ccc);
rex = null;
return bux;
}; // EnDe.split
this.trim = function(src) {
//#? trim leading and trailing white spaces
if (src===undefined) { return src; } // some JavaScript engines are picky
while (src.substring(0, 1)===' ') {
src = src.substring(1, src.length);
}
while (src.substring(src.length-1, src.length)===' ') {
src = src.substring(0, src.length-1);
}
return src;
}; // EnDe.trim
this.chr2bytes = function(src) {
//#? convert (unicode) character to array of 1 or 2 bytes; src is a single character
var bux = [];
var ccc = src.charCodeAt(0);
var c1 = 0, c2 = 0;
if (ccc<256) { // 1 byte
bux.push(ccc);
} else if(ccc<65536) { // 2 bytes
c1 = ccc >> 8;
c2 = ccc - (c1*256);
bux.push(c1);
bux.push(c2);
} else { // 3 bytes
// ToDo: not supported
}
ccc = null; c1 = null; c2 = null;
return bux;
}; // EnDe.chr2bytes
this.str2bytes = function(src) {
//#? convert (unicode) character string to array of bytes
var bux = [], kkk = [];
var i = 0;
if (src.length < EnDe.CONST.CST.blocksize) {
/* this case just for documentation how it should be
* but this results in crappy perfromance with JavaScript
* see comment about EnDe.CONST.CST.blocksize also */
for (i=0; i<src.length; i++) {
bux = bux.concat(this.chr2bytes(src[i]));
}
} else {
for (i=0; i<src.length; i++) {
kkk = kkk.concat(this.chr2bytes(src[i]));
if (kkk.length >= EnDe.CONST.CST.blocksize) { bux = bux.concat(kkk); kkk.length = 0; }
}
bux = bux.concat(kkk);
kkk.length = 0;
}
return bux;
}; // EnDe.str2bytes
this.chr2code = function(src) {
//#? convert plain text to JavaScript char codes (integer of unicode); src is a single character
// ToDo: this.dez(), this.ncr() and this.ucs() are very similar
var bux = '';
var i = 0;
for (i=0; i<src.length; i++) {
bux += src.charCodeAt(i);
if (i<(src.length-1)) {
bux += ',';
}
}
return bux;
}; // EnDe.chr2code
this.chr2bin_DoesNotWork = function(type,src) {
//#? convert character to n-bit binary string; src is a single character; type is number of bits
var bux = '';
var i = 0;
for (i=(type-1); i>-1; i--) {
if (src >= Math.pow(2,i)) {
src -= Math.pow(2,i);
bin += '1';
} else {
bin += '0';
}
}
return bux;
}; // chr2bin_DoesNotWork
this.chr2bin = function(type,src) {
//#? convert character to n-bit binary string; src is a single character; type is number of bits
var bux = '';
var i = 0;
for (i=0; i<type; i++) {
if (src >= Math.pow(2,(type-1)-i)) {
src -= Math.pow(2,(type-1)-i);
bux += '1';
} else {
bux += '0';
}
}
return bux;
}; // EnDe.chr2bin
this.java2chr = function(src) {
//#? convert char code to character using java.lang.Character()
var bux = '';
var i = 0;
while (i<src.length) {
bux += java.lang.Character(src.charCodeAt(i));
i++;
}
return bux;
}; // EnDe.java2chr
this.code2chr = function(src) {
//#? convert JavaScript char codes (integer of unicode) to plain text
// ToDo: EnDe.DE.dez() is very similar
var bux = '';
var ccc = '';
var kkk = src.split(',');
while ((ccc=kkk.shift())!==undefined) {
// TODo: loop obsolete wenn die Integer durch , getrennt
bux += String.fromCharCode(ccc);
}
return bux;
}; // EnDe.code2chr
this.code2prn = function(src) {
//#? convert JavaScript char code (integer of unicode) to printable (ASCII) character
/*
* src is a single character
* NOTE: this is not a real conversion/coding just pretty printing!
*/
var bux = '';
var ccc = String.fromCharCode(src);
if ((src > 31) && (src <= 127)) {
bux += ' ' + ccc;
} else if ((src > 127) && (src <= 255)) {
bux += ' ' + ccc;
} else if ((src > 255) && (src <= 65635)) {
bux += ' ' + ccc;
} else if ((src > 65635)) {
bux += ' ' + ccc;
} else {
switch(src) {
case 0: bux += '\\0'; break;
case 7: bux += '\\b'; break;
case 8: bux += '\\v'; break;
case 9: bux += '\\t'; break;
case 10: bux += '\\n'; break;
case 13: bux += '\\r'; break;
default: bux += ' .'; break;
}
}
return bux;
}; // EnDe.code2prn
this.prn2code = function(src) {
//#? convert printable (ASCII) character to JavaScript char code (integer of unicode)
/*
* NOTE: this is not a real conversion/coding just pretty printing!
*/
var bux = '';
var i = 0;
while (i < src.length) {
if (src[i]==='\\') {
switch(src[i+1]) {
case '0': bux += '\0'; break;
case 'b': bux += '\b'; break;
case 'h': bux += '\h'; break;
case 'v': bux += '\v'; break;
case 't': bux += '\t'; break;
case 'n': bux += '\n'; break;
case 'r': bux += '\r'; break;
default: bux += src[i] + src[i+1]; break;
}
i++;
} else { bux += src[i]; }
i++;
}
return bux;
}; // EnDe.prn2code
this.chr2prn = function(type,src) {
//#? convert JavaScript character to printable (ASCII) character, non-printable are \xXX
//#type? null: convert non-printable to hex (no padding, see EnDe.i2h())
//#type? 3: convert non-printable to 3-digit hex (see EnDe.i2h())
//#type? n: convert non-printable to n-digit hex (see EnDe.i2h())
// ToDo: to be integrated into EnDeMenu.js (but concept mssing how to
// pass new mode "Straight -> Hex (ASCII only)"
var bux = '';
var ccc = '';
var i = 0;
for (i=0; i<src.length; i++) {
ccc = src.charCodeAt(i);
if ((ccc > 31) && (ccc <= 127) && (ccc != 92)) { // all except \ (backslash)
bux += String.fromCharCode(ccc);
} else {
bux += '\\x' + EnDe.i2h(type,src.charCodeAt(i));
}
}
ccc = '';
return bux;
}; // EnDe.chr2prn
this.str2bin = function(type,src,prefix,suffix,delimiter) {
//#? convert string to n-bit binary string; type is number of bits
var bux = '';
var i = 0;
for (i=0; i < src.length; i++) {
bux += delimiter + prefix + EnDe.chr2bin(type,src.charCodeAt(i).toString()) + suffix;
}
bux = bux.substring(delimiter.length, bux.length); // remove leading delimiter
return bux;
}; // EnDe.str2bin
this.str2chr = function(src,prefix,suffix,delimiter) {
//#? convert string to list of characters with prefix, delimiter and suffix
return prefix + src.split('').join(suffix + delimiter + prefix) + suffix
}; // EnDe.str2chr
this.str2lng = function(src) {
//#? convert a string to an array of long integers
if (typeof(src) == 'number') {
// ToDo: not really correct, should depend on strict mode
return src;
}
var len = Math.ceil(src.length/4);
var arr = new Array(len);
var i = 0;
for (i=0; i<len; i++) {
// ToDo: * oder >>
arr[i] = src.charCodeAt( i*4) +
(src.charCodeAt((i*4) + 1)<<8 ) +
(src.charCodeAt((i*4) + 2)<<16) +
(src.charCodeAt((i*4) + 3)<<24);
}
return arr;
}; // EnDe.str2lng
this.lng2str = function(src) {
//#? convert an array of long integers to a string
var arr = new Array(src.length);
var i = 0;
for (i=0; i<arr.length; i++) {
arr[i] = String.fromCharCode(
src[i] & 0xff,
src[i]>>>8 & 0xff,
src[i]>>>16 & 0xff,
src[i]>>>24 & 0xff
);
}
return arr.join('');
}; // EnDe.lng2str
// ===================================================================== //
// global number convertion functions //
// ===================================================================== //
this.z2n = function(src) {
//#? convert negative numbers to numbers (2^32)
var bux = parseInt(src, 10);
if (bux < 0) {
// if negative we try to treat the number as (2^32)
if (bux > -EnDe.CONST.INT.MAX31) {
bux = bux + EnDe.CONST.INT.exp32;
}
}
return bux;
}; // EnDe.z2n
this.n2z = function(src) {
//#? convert numbers (2^32) to negative numbers
var bux = parseInt(src, 10);
if (bux > EnDe.CONST.INT.MAX31) {
bux = bux - EnDe.CONST.INT.exp32;
}
return bux;
}; // EnDe.n2z
this.z2n64 = function(src) {
//#? convert negative numbers to numbers (2^64)
// Note that number > .INT.MAX53 throw an exception
var bux = parseInt(src, 10);
if (bux < 0) {
// if negative we try to treat the number as (2^64)
if (bux > -EnDe.CONST.INT.MAX63) {
bux = bux + EnDe.CONST.INT.exp64;
}
}
return bux;
}; // EnDe.z2n64
this.n2z64 = function(src) {
//#? convert numbers (2^64) to negative numbers
// Note that number > .INT.MAX53 throw an exception
var bux = parseInt(src, 10);
if (bux > EnDe.CONST.INT.MAX63) {
bux = bux - EnDe.CONST.INT.exp64;
}
return bux;
}; // EnDe.n2z64
this.h2i = function(src) {
//#? convert hex value (string) to integer
var bux = parseInt(src, 16).toString(10);
if (isNaN(bux)) { return ''; } // ToDo: depends on mode what to do here
return bux;
}; // EnDe.h2i
this.i2h = function(type,src) {
//#? convert integer (string) value to hex
//#type? null: converted hex (no padding)
//#type? hex0: converted hex (no padding)
//#type? hex1: converted hex (no padding)
//#type? 3: converted 3-digit hex
//#type? n: converted n-digit hex
if ((src!==0) && (src==='')) { return ''; } // ToDo: depends on mode what to do here
/*
* (src != 0) check necessary for buggy Mozilla, which treats a binary 0
* as an empty string too :-((
*/
var bux = parseInt(src, 10).toString(16);
var kkk = 2;
if (bux.match(/[^0-9a-f]/i)!==null) { return ''; } // ToDo: depends on mode what to do here (should only occour if parseInt() returned NaN)
switch (type) {
case 'null':
case 'hex0':
case 'hex1': kkk = 1; break;
default :
kkk = parseInt(type, 10);
if (isNaN(kkk)) { kkk = 1; }
break;
}
while (bux.length<kkk) { bux = '0' + bux; }
return bux;
}; // EnDe.i2h
this.c2h = function(src) {
//#? convert (Unicode) characters to hex value (string)
var bux = '';
var i = 0;
var ccc = null;
var hex = new Array ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
for (i=0; i<src.length; i++) {
ccc = src.charCodeAt(i);
if (ccc > 255){
// convert left byte
bux += hex[(ccc>>8) >> 4] + hex[(ccc>>8) & 0xf];
ccc &= 0xff;
// convert right byte
}
bux += hex[ccc >> 4] + hex[ccc & 0xf];
}
return bux;
}; // EnDe.c2h
this.h2c = function(src) {
//#? convert hex value (string) to characters
/* this is the same as EnDe.EN.hex(2,'','','',''); */
var bux = '';
var ccc = null;
var i = 0;
for (i=0; i<src.length; i+=2) {
ccc = parseInt(src[i]+src[i+1], 16);
if (isNaN(ccc)) { // ToDo: depends on mode what to do here
bux += src[i] + src[i+1];
} else {
bux += String.fromCharCode(parseInt(src[i]+src[i+1], 16));
}
}
return bux;
}; // EnDe.h2c
this.h2b = function(src) {
//#? convert hex value (string) to binary
var bux = parseInt(src, 16).toString(2);
if (isNaN(bux)) { return ''; } // ToDo: depends on mode what to do here
return bux;
}; // EnDe.h2b
this.b2h = function(src) {
//#? convert binary value (string) to hex (binary limeted to 2^53)
//ToDo: if src > this.MAX53 the result may be random
var bux = parseInt(src, 2).toString(16);
if (bux==='NaN') { return ''; } // ToDo: depends on mode what to do here
/* Note: NaN is only returned if converion fails,
* cannot use isNaN() 'cause it would return false for hex values
*/
if ((bux==='1') && (src!=='1')) { return ''; } // ToDo: 2^53 overflow
return bux;
}; // EnDe.b2h
this.i2b = function(src) {
//#? convert integer (string) value to binary
var bux = parseInt(src, 10).toString(2);
if (isNaN(bux)) { return ''; } // ToDo: depends on mode what to do here
return bux;
}; // EnDe.i2b
this.b2i = function(src) {
//#? convert binary value (string) to hex (binary limeted to 2^53)
//ToDo: if src > this.MAX53 the result may be random
var bux = parseInt(src, 2).toString(10);
if ((bux==='1') && (src!=='1')) { return ''; } // ToDo: 2^53 overflow
if (isNaN(bux)) { return ''; } // ToDo: depends on mode what to do here
return bux;
}; // EnDe.b2i
this.i2bcd = function(src) {
//#? convert digit to BCD code (4 dual digits)
var bux = parseInt(src, 10).toString(2);
while (bux.length < 4) { bux = '0' + bux; }
return bux;
}; // EnDe.i2bcd
this.bcd2i = function(src) {
//#? convert BCD code (4 dual digits) to digit
if (src.match(/^0+$/)!== null) { return '0'; }
var bux = src.replace(/^0/g, '');
bux = parseInt(bux, 2).toString(10);
if (isNaN(bux)) { return src; }
if (bux > 9) { return src; }
return bux;
}; // EnDe.bcd2i
// ===================================================================== //
// global symetric en-, decoding functions //
// ===================================================================== //
this.reverse = function(src) {
//#? reverse characters in string (mirror sring)
return src.split('').reverse().join('');
}; // EnDe.reverse
this.atbash = function(src) {
//#? convert plain text to Atbash encoding
var bux = '';
var ccc = 0;
var i = 0;
for (i=0; i<src.length; i++) {
ccc = src.charCodeAt(i);
if ((64<ccc) && (ccc<91)) {
bux += String.fromCharCode((((78-ccc)*2)-1+ccc));
continue;
}
if ((96<ccc) && (ccc<123)) {
bux += String.fromCharCode((((110-ccc)*2)-1+ccc));
continue;
}
bux += src[i];
}
return bux;
}; // EnDe.atbash
this.a2e = function(src) {
//#? convert ASCII to EBCDIC characters
var bux = '';
var ccc = 0;
var i = 0;
for(i=0; i<src.length; i++) {
ccc = src.charCodeAt(i);
if (ccc > 255) {
bux += '[EnDe.a2e: value ('+src[i]+'='+ccc+') out of range]'; // ToDo: depends on mode what to do here
continue;
}
bux += String.fromCharCode(EnDe.a2eMap[ccc]);
}
return bux;
}; // EnDe.a2e
this.e2a = function(src) {
//#? convert EBCDIC to ASCII characters
var bux = '';
var ccc = 0;
var i = 0;
for(i=0; i<src.length; i++) {
ccc = src.charCodeAt(i);
if (ccc > 255) {
bux += '[EnDe.e2a: value ('+src[i]+'='+ccc+') out of range]'; // ToDo: depends on mode what to do here
continue;
}
bux += String.fromCharCode(EnDe.e2aMap[ccc]);
}
return bux;
}; // EnDe.e2a
this.xor = function(src,key) {
//#? XOR each character with first character from key
var bux = '';
var xor = key.charCodeAt();
var i = 0;
for (i=0; i<src.length; i++) {
bux += String.fromCharCode(xor^src.charCodeAt(i));
}
return bux;
}; // EnDe.xor
this.rot = function(src,key) {
//#? convert string to rot-N-encoded text (aka Caesar encoding); key is number/position of character: 1..26
var bux = '';
var kkk = '';
var i = 0;
var b;
if ((key<1) || (key>26)) { return src; }
for(i=0; i<src.length; i++) {
kkk = 0;
b = src.charCodeAt(i);
if (b>96) { kkk = 32; }
b -= kkk;
if ((b>64) && (b<91)) {
b += key;
if (b>90) { b -= 26; }
}
b += kkk;
bux += String.fromCharCode(b);
}
return bux;
}; // EnDe.rot
// ===================================================================== //
// global convertion functions //
// ===================================================================== //
this.dez2hex = function(type,mode,uppercase,src,prefix,suffix,_n7_) {
//#? convert decimal encoded text to hex encoded text
//#type? null: converted hex value without prefix
//#type? qp2: converted hex value prefixed with =
//#type? url2: converted hex value prefixed with %
//#type? url3: converted hex value prefixed with %0
//#type? url4: converted hex value prefixed with %00
//#type? ncr2: converted hex value prefixed with &#x
//#type? ncr4: converted hex value prefixed with �
var bux = '';
var pre = '';
var modulo = 2;
switch (type) {
case 'null' : pre = ''; modulo = 9999; break; //quick&dirty
case 'qp2' : pre = '='; modulo = 2; break;
case 'url2' : pre = '%'; modulo = 2; break;
case 'url3' : pre = '%'; modulo = 2; break;
case 'url4' : pre = '%'; modulo = 4; break;
case 'ncr2' : pre = '&#x'; break;
case 'ncr4' : pre = '�'; break; // ToDo: buggy for chr>255
default : pre = ''; modulo = 9999; break;
}
if(src===0) { return pre + '00'; }
var mask = 0xf;
var pos = 1;
var bbb = '';
var kkk = '';
while (src != 0) {
// ToDo: probably fails if src ends with 0-byte
kkk = this.CONST.CHR.hex.charAt(src & mask);
if (uppercase) {
kkk = kkk.toUpperCase();
}
bbb = kkk + bbb;
if ((pos % modulo)===0) {
if ((bbb.length===1) || (bbb.length===3)) { // quick&dirty
// pad with zero (pre also missing)
bbb = '0' + bbb;
}
bux = pre + bbb + bux;
if (src > 255) { // quick&dirty
bux = suffix + bux;
}
bbb = '';
}
pos++;
src>>>=4;
}
if (bbb!=='') {
if ((bbb.length===1) || (bbb.length===3)) { // quick&dirty
// pad with zero (pre also missing)
bbb = '0' + bbb;
}