1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package goldengate.common.digest;
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.nio.ByteBuffer;
30 import java.nio.channels.FileChannel;
31 import java.util.Arrays;
32
33 import org.jboss.netty.buffer.ChannelBuffer;
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 public class MD5 {
127
128
129
130 private MD5State state;
131
132
133
134
135
136 private MD5State finals;
137
138
139
140
141 private static byte padding[] = {
142 (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
145
146 private static boolean native_lib_loaded = false;
147
148 private static boolean native_lib_init_pending = true;
149
150 private static String native_lib_path = "D:/somewhere/goldengate/lib/arch/win32_x86/MD5.dll";
151
152
153
154
155
156 public synchronized void Init() {
157 state = new MD5State();
158 finals = null;
159 }
160
161
162
163
164 public MD5() {
165 if (native_lib_init_pending) {
166 _initNativeLibrary();
167 }
168 Init();
169 }
170
171
172
173
174
175
176
177
178 public MD5(Object ob) {
179 this();
180 Update(ob.toString());
181 }
182
183 private void Decode(byte buffer[], int shift, int[] out) {
184
185
186
187
188
189
190
191
192 out[0] = buffer[shift] & 0xff | (buffer[shift + 1] & 0xff) << 8 |
193 (buffer[shift + 2] & 0xff) << 16 | buffer[shift + 3] << 24;
194 out[1] = buffer[shift + 4] & 0xff | (buffer[shift + 5] & 0xff) << 8 |
195 (buffer[shift + 6] & 0xff) << 16 | buffer[shift + 7] << 24;
196 out[2] = buffer[shift + 8] & 0xff | (buffer[shift + 9] & 0xff) << 8 |
197 (buffer[shift + 10] & 0xff) << 16 | buffer[shift + 11] << 24;
198 out[3] = buffer[shift + 12] & 0xff | (buffer[shift + 13] & 0xff) << 8 |
199 (buffer[shift + 14] & 0xff) << 16 | buffer[shift + 15] << 24;
200 out[4] = buffer[shift + 16] & 0xff | (buffer[shift + 17] & 0xff) << 8 |
201 (buffer[shift + 18] & 0xff) << 16 | buffer[shift + 19] << 24;
202 out[5] = buffer[shift + 20] & 0xff | (buffer[shift + 21] & 0xff) << 8 |
203 (buffer[shift + 22] & 0xff) << 16 | buffer[shift + 23] << 24;
204 out[6] = buffer[shift + 24] & 0xff | (buffer[shift + 25] & 0xff) << 8 |
205 (buffer[shift + 26] & 0xff) << 16 | buffer[shift + 27] << 24;
206 out[7] = buffer[shift + 28] & 0xff | (buffer[shift + 29] & 0xff) << 8 |
207 (buffer[shift + 30] & 0xff) << 16 | buffer[shift + 31] << 24;
208 out[8] = buffer[shift + 32] & 0xff | (buffer[shift + 33] & 0xff) << 8 |
209 (buffer[shift + 34] & 0xff) << 16 | buffer[shift + 35] << 24;
210 out[9] = buffer[shift + 36] & 0xff | (buffer[shift + 37] & 0xff) << 8 |
211 (buffer[shift + 38] & 0xff) << 16 | buffer[shift + 39] << 24;
212 out[10] = buffer[shift + 40] & 0xff | (buffer[shift + 41] & 0xff) << 8 |
213 (buffer[shift + 42] & 0xff) << 16 | buffer[shift + 43] << 24;
214 out[11] = buffer[shift + 44] & 0xff | (buffer[shift + 45] & 0xff) << 8 |
215 (buffer[shift + 46] & 0xff) << 16 | buffer[shift + 47] << 24;
216 out[12] = buffer[shift + 48] & 0xff | (buffer[shift + 49] & 0xff) << 8 |
217 (buffer[shift + 50] & 0xff) << 16 | buffer[shift + 51] << 24;
218 out[13] = buffer[shift + 52] & 0xff | (buffer[shift + 53] & 0xff) << 8 |
219 (buffer[shift + 54] & 0xff) << 16 | buffer[shift + 55] << 24;
220 out[14] = buffer[shift + 56] & 0xff | (buffer[shift + 57] & 0xff) << 8 |
221 (buffer[shift + 58] & 0xff) << 16 | buffer[shift + 59] << 24;
222 out[15] = buffer[shift + 60] & 0xff | (buffer[shift + 61] & 0xff) << 8 |
223 (buffer[shift + 62] & 0xff) << 16 | buffer[shift + 63] << 24;
224 }
225
226 private native void TransformJni(int[] stat, byte buffer[], int shift,
227 int length);
228
229 private void Transform(MD5State stat, byte buffer[], int shift,
230 int[] decode_buf) {
231 int a = stat.state[0], b = stat.state[1], c = stat.state[2], d = stat.state[3], x[] = decode_buf;
232
233 Decode(buffer, shift, decode_buf);
234
235
236 a += (b & c | ~b & d) + x[0] + 0xd76aa478;
237 a = (a << 7 | a >>> 25) + b;
238 d += (a & b | ~a & c) + x[1] + 0xe8c7b756;
239 d = (d << 12 | d >>> 20) + a;
240 c += (d & a | ~d & b) + x[2] + 0x242070db;
241 c = (c << 17 | c >>> 15) + d;
242 b += (c & d | ~c & a) + x[3] + 0xc1bdceee;
243 b = (b << 22 | b >>> 10) + c;
244
245 a += (b & c | ~b & d) + x[4] + 0xf57c0faf;
246 a = (a << 7 | a >>> 25) + b;
247 d += (a & b | ~a & c) + x[5] + 0x4787c62a;
248 d = (d << 12 | d >>> 20) + a;
249 c += (d & a | ~d & b) + x[6] + 0xa8304613;
250 c = (c << 17 | c >>> 15) + d;
251 b += (c & d | ~c & a) + x[7] + 0xfd469501;
252 b = (b << 22 | b >>> 10) + c;
253
254 a += (b & c | ~b & d) + x[8] + 0x698098d8;
255 a = (a << 7 | a >>> 25) + b;
256 d += (a & b | ~a & c) + x[9] + 0x8b44f7af;
257 d = (d << 12 | d >>> 20) + a;
258 c += (d & a | ~d & b) + x[10] + 0xffff5bb1;
259 c = (c << 17 | c >>> 15) + d;
260 b += (c & d | ~c & a) + x[11] + 0x895cd7be;
261 b = (b << 22 | b >>> 10) + c;
262
263 a += (b & c | ~b & d) + x[12] + 0x6b901122;
264 a = (a << 7 | a >>> 25) + b;
265 d += (a & b | ~a & c) + x[13] + 0xfd987193;
266 d = (d << 12 | d >>> 20) + a;
267 c += (d & a | ~d & b) + x[14] + 0xa679438e;
268 c = (c << 17 | c >>> 15) + d;
269 b += (c & d | ~c & a) + x[15] + 0x49b40821;
270 b = (b << 22 | b >>> 10) + c;
271
272
273 a += (b & d | c & ~d) + x[1] + 0xf61e2562;
274 a = (a << 5 | a >>> 27) + b;
275 d += (a & c | b & ~c) + x[6] + 0xc040b340;
276 d = (d << 9 | d >>> 23) + a;
277 c += (d & b | a & ~b) + x[11] + 0x265e5a51;
278 c = (c << 14 | c >>> 18) + d;
279 b += (c & a | d & ~a) + x[0] + 0xe9b6c7aa;
280 b = (b << 20 | b >>> 12) + c;
281
282 a += (b & d | c & ~d) + x[5] + 0xd62f105d;
283 a = (a << 5 | a >>> 27) + b;
284 d += (a & c | b & ~c) + x[10] + 0x02441453;
285 d = (d << 9 | d >>> 23) + a;
286 c += (d & b | a & ~b) + x[15] + 0xd8a1e681;
287 c = (c << 14 | c >>> 18) + d;
288 b += (c & a | d & ~a) + x[4] + 0xe7d3fbc8;
289 b = (b << 20 | b >>> 12) + c;
290
291 a += (b & d | c & ~d) + x[9] + 0x21e1cde6;
292 a = (a << 5 | a >>> 27) + b;
293 d += (a & c | b & ~c) + x[14] + 0xc33707d6;
294 d = (d << 9 | d >>> 23) + a;
295 c += (d & b | a & ~b) + x[3] + 0xf4d50d87;
296 c = (c << 14 | c >>> 18) + d;
297 b += (c & a | d & ~a) + x[8] + 0x455a14ed;
298 b = (b << 20 | b >>> 12) + c;
299
300 a += (b & d | c & ~d) + x[13] + 0xa9e3e905;
301 a = (a << 5 | a >>> 27) + b;
302 d += (a & c | b & ~c) + x[2] + 0xfcefa3f8;
303 d = (d << 9 | d >>> 23) + a;
304 c += (d & b | a & ~b) + x[7] + 0x676f02d9;
305 c = (c << 14 | c >>> 18) + d;
306 b += (c & a | d & ~a) + x[12] + 0x8d2a4c8a;
307 b = (b << 20 | b >>> 12) + c;
308
309
310 a += (b ^ c ^ d) + x[5] + 0xfffa3942;
311 a = (a << 4 | a >>> 28) + b;
312 d += (a ^ b ^ c) + x[8] + 0x8771f681;
313 d = (d << 11 | d >>> 21) + a;
314 c += (d ^ a ^ b) + x[11] + 0x6d9d6122;
315 c = (c << 16 | c >>> 16) + d;
316 b += (c ^ d ^ a) + x[14] + 0xfde5380c;
317 b = (b << 23 | b >>> 9) + c;
318
319 a += (b ^ c ^ d) + x[1] + 0xa4beea44;
320 a = (a << 4 | a >>> 28) + b;
321 d += (a ^ b ^ c) + x[4] + 0x4bdecfa9;
322 d = (d << 11 | d >>> 21) + a;
323 c += (d ^ a ^ b) + x[7] + 0xf6bb4b60;
324 c = (c << 16 | c >>> 16) + d;
325 b += (c ^ d ^ a) + x[10] + 0xbebfbc70;
326 b = (b << 23 | b >>> 9) + c;
327
328 a += (b ^ c ^ d) + x[13] + 0x289b7ec6;
329 a = (a << 4 | a >>> 28) + b;
330 d += (a ^ b ^ c) + x[0] + 0xeaa127fa;
331 d = (d << 11 | d >>> 21) + a;
332 c += (d ^ a ^ b) + x[3] + 0xd4ef3085;
333 c = (c << 16 | c >>> 16) + d;
334 b += (c ^ d ^ a) + x[6] + 0x04881d05;
335 b = (b << 23 | b >>> 9) + c;
336
337 a += (b ^ c ^ d) + x[9] + 0xd9d4d039;
338 a = (a << 4 | a >>> 28) + b;
339 d += (a ^ b ^ c) + x[12] + 0xe6db99e5;
340 d = (d << 11 | d >>> 21) + a;
341 c += (d ^ a ^ b) + x[15] + 0x1fa27cf8;
342 c = (c << 16 | c >>> 16) + d;
343 b += (c ^ d ^ a) + x[2] + 0xc4ac5665;
344 b = (b << 23 | b >>> 9) + c;
345
346
347 a += (c ^ (b | ~d)) + x[0] + 0xf4292244;
348 a = (a << 6 | a >>> 26) + b;
349 d += (b ^ (a | ~c)) + x[7] + 0x432aff97;
350 d = (d << 10 | d >>> 22) + a;
351 c += (a ^ (d | ~b)) + x[14] + 0xab9423a7;
352 c = (c << 15 | c >>> 17) + d;
353 b += (d ^ (c | ~a)) + x[5] + 0xfc93a039;
354 b = (b << 21 | b >>> 11) + c;
355
356 a += (c ^ (b | ~d)) + x[12] + 0x655b59c3;
357 a = (a << 6 | a >>> 26) + b;
358 d += (b ^ (a | ~c)) + x[3] + 0x8f0ccc92;
359 d = (d << 10 | d >>> 22) + a;
360 c += (a ^ (d | ~b)) + x[10] + 0xffeff47d;
361 c = (c << 15 | c >>> 17) + d;
362 b += (d ^ (c | ~a)) + x[1] + 0x85845dd1;
363 b = (b << 21 | b >>> 11) + c;
364
365 a += (c ^ (b | ~d)) + x[8] + 0x6fa87e4f;
366 a = (a << 6 | a >>> 26) + b;
367 d += (b ^ (a | ~c)) + x[15] + 0xfe2ce6e0;
368 d = (d << 10 | d >>> 22) + a;
369 c += (a ^ (d | ~b)) + x[6] + 0xa3014314;
370 c = (c << 15 | c >>> 17) + d;
371 b += (d ^ (c | ~a)) + x[13] + 0x4e0811a1;
372 b = (b << 21 | b >>> 11) + c;
373
374 a += (c ^ (b | ~d)) + x[4] + 0xf7537e82;
375 a = (a << 6 | a >>> 26) + b;
376 d += (b ^ (a | ~c)) + x[11] + 0xbd3af235;
377 d = (d << 10 | d >>> 22) + a;
378 c += (a ^ (d | ~b)) + x[2] + 0x2ad7d2bb;
379 c = (c << 15 | c >>> 17) + d;
380 b += (d ^ (c | ~a)) + x[9] + 0xeb86d391;
381 b = (b << 21 | b >>> 11) + c;
382
383 stat.state[0] += a;
384 stat.state[1] += b;
385 stat.state[2] += c;
386 stat.state[3] += d;
387 }
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403 public void Update(MD5State stat, byte buffer[], int offset, int length) {
404 int index, partlen, i, start;
405 finals = null;
406 int newlength = length;
407
408 if (newlength + offset > buffer.length) {
409 newlength = buffer.length - offset;
410 }
411
412
413
414 index = (int) (stat.count & 0x3f);
415 stat.count += newlength;
416
417 partlen = 64 - index;
418
419 if (newlength >= partlen) {
420 if (native_lib_loaded) {
421
422
423
424 if (partlen == 64) {
425 partlen = 0;
426 } else {
427 for (i = 0; i < partlen; i ++) {
428 stat.buffer[i + index] = buffer[i + offset];
429 }
430 TransformJni(stat.state, stat.buffer, 0, 64);
431 }
432 i = partlen + ((newlength - partlen) / 64) * 64;
433
434
435
436 int transformLength = newlength - partlen;
437 int transformOffset = partlen + offset;
438 final int MAX_LENGTH = 65536;
439 while (true) {
440 if (transformLength > MAX_LENGTH) {
441 TransformJni(stat.state, buffer, transformOffset, MAX_LENGTH);
442 transformLength -= MAX_LENGTH;
443 transformOffset += MAX_LENGTH;
444 } else {
445 TransformJni(stat.state, buffer, transformOffset, transformLength);
446 break;
447 }
448 }
449
450
451
452
453 } else {
454
455
456
457 int[] decode_buf = new int[16];
458 if (partlen == 64) {
459 partlen = 0;
460 } else {
461 for (i = 0; i < partlen; i ++) {
462 stat.buffer[i + index] = buffer[i + offset];
463 }
464 Transform(stat, stat.buffer, 0, decode_buf);
465 }
466 for (i = partlen; i + 63 < newlength; i += 64) {
467 Transform(stat, buffer, i + offset, decode_buf);
468 }
469 }
470 index = 0;
471 } else {
472 i = 0;
473 }
474
475
476 if (i < newlength) {
477 start = i;
478 for (; i < newlength; i ++) {
479 stat.buffer[index + i - start] = buffer[i + offset];
480 }
481 }
482 }
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497 public void Update(byte buffer[], int offset, int length) {
498 Update(state, buffer, offset, length);
499 }
500
501
502
503
504
505
506
507 public void Update(byte buffer[], int length) {
508 Update(state, buffer, 0, length);
509 }
510
511
512
513
514
515
516
517 public void Update(byte buffer[]) {
518 Update(buffer, 0, buffer.length);
519 }
520
521
522
523
524
525
526
527 public void Update(byte b) {
528 byte buffer[] = new byte[1];
529 buffer[0] = b;
530
531 Update(buffer, 1);
532 }
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548 public void Update(String s) {
549 byte chars[] = s.getBytes();
550 Update(chars, chars.length);
551 }
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566 public void Update(String s, String charset_name)
567 throws java.io.UnsupportedEncodingException {
568 String newcharset = charset_name;
569 if (newcharset == null) {
570 newcharset = "ISO8859_1";
571 }
572 byte chars[] = s.getBytes(newcharset);
573 Update(chars, chars.length);
574 }
575
576
577
578
579
580
581
582
583 public void Update(int i) {
584 Update((byte) (i & 0xff));
585 }
586
587
588
589
590
591
592
593 public void Update(ChannelBuffer buffer) {
594 byte[] bytes;
595 int start = 0;
596 int len = buffer.readableBytes();
597 if (buffer.hasArray()) {
598 start = buffer.arrayOffset();
599 bytes = buffer.array();
600 if (bytes.length > start+len) {
601 byte[] temp = new byte[len];
602 System.arraycopy(bytes, start, temp, 0, len);
603 start = 0;
604 bytes = temp;
605 }
606 } else {
607 bytes = new byte[len];
608 buffer.getBytes(start, bytes);
609 }
610 Update(state, bytes, start, len);
611 }
612
613 private byte[] Encode(int input[], int len) {
614 int i, j;
615 byte out[];
616
617 out = new byte[len];
618
619 for (i = j = 0; j < len; i ++, j += 4) {
620 out[j] = (byte) (input[i] & 0xff);
621 out[j + 1] = (byte) (input[i] >>> 8 & 0xff);
622 out[j + 2] = (byte) (input[i] >>> 16 & 0xff);
623 out[j + 3] = (byte) (input[i] >>> 24 & 0xff);
624 }
625
626 return out;
627 }
628
629
630
631
632
633
634
635
636 public synchronized byte[] Final() {
637 byte bits[];
638 int index, padlen;
639 MD5State fin;
640
641 if (finals == null) {
642 fin = new MD5State(state);
643
644 int[] count_ints = {
645 (int) (fin.count << 3), (int) (fin.count >> 29) };
646 bits = Encode(count_ints, 8);
647
648 index = (int) (fin.count & 0x3f);
649 padlen = index < 56? 56 - index : 120 - index;
650
651 Update(fin, padding, 0, padlen);
652 Update(fin, bits, 0, 8);
653
654
655 finals = fin;
656 }
657
658 return Encode(finals.state, 16);
659 }
660
661 private static final char[] HEX_CHARS = {
662 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
663 'd', 'e', 'f', };
664
665
666
667
668
669
670
671
672
673 public static final String asHex(byte hash[]) {
674 char buf[] = new char[hash.length * 2];
675 for (int i = 0, x = 0; i < hash.length; i ++) {
676 buf[x ++] = HEX_CHARS[hash[i] >>> 4 & 0xf];
677 buf[x ++] = HEX_CHARS[hash[i] & 0xf];
678 }
679 return new String(buf);
680 }
681
682
683
684
685
686
687
688
689
690 public static final byte[] asByte(String buf) {
691 byte from[] = buf.getBytes();
692 byte hash[] = new byte[from.length / 2];
693 for (int i = 0, x = 0; i < hash.length; i ++) {
694 byte code1 = from[x ++];
695 byte code2 = from[x ++];
696 if (code1 >= HEX_CHARS[10]) {
697 code1 -= HEX_CHARS[10] - 10;
698 } else {
699 code1 -= HEX_CHARS[0];
700 }
701 if (code2 >= HEX_CHARS[10]) {
702 code2 -= HEX_CHARS[10] - 10;
703 } else {
704 code2 -= HEX_CHARS[0];
705 }
706 hash[i] = (byte) ((code1 << 4) + code2);
707 }
708 return hash;
709 }
710
711
712
713
714
715
716 public String asHex() {
717 return asHex(Final());
718 }
719
720
721
722
723
724
725
726 public static synchronized final boolean initNativeLibrary(
727 boolean disallow_lib_loading) {
728 if (disallow_lib_loading) {
729 native_lib_init_pending = false;
730 return false;
731 }
732 return _initNativeLibrary();
733 }
734
735
736
737
738
739
740
741 public static synchronized final boolean initNativeLibrary(String libpath) {
742 native_lib_path = libpath;
743 native_lib_init_pending = true;
744 return _initNativeLibrary();
745 }
746
747
748
749
750
751
752 private static synchronized final boolean _initNativeLibrary() {
753 if (!native_lib_init_pending) {
754 return native_lib_loaded;
755 }
756 native_lib_loaded = _loadNativeLibrary();
757
758 native_lib_init_pending = false;
759 return native_lib_loaded;
760 }
761
762
763
764
765
766
767 private static synchronized final boolean _loadNativeLibrary() {
768 try {
769
770
771 String prop = System
772 .getProperty("com.twmacinta.util.MD5.NO_NATIVE_LIB");
773 if (prop != null) {
774 prop = prop.trim();
775 if (prop.equalsIgnoreCase("true") || prop.equals("1")) {
776 return false;
777 }
778 }
779
780
781 File fstring;
782 prop = native_lib_path;
783 if (prop != null) {
784 fstring = new File(prop);
785 if (fstring.canRead()) {
786 System.load(fstring.getAbsolutePath());
787 return true;
788 }
789 }
790
791
792 File f;
793 prop = System.getProperty("com.twmacinta.util.MD5.NATIVE_LIB_FILE");
794 if (prop != null) {
795 f = new File(prop);
796 if (f.canRead()) {
797 System.load(f.getAbsolutePath());
798 return true;
799 }
800 }
801
802
803 String os_name = System.getProperty("os.name");
804 String os_arch = System.getProperty("os.arch");
805 if (os_name == null || os_arch == null) {
806 return false;
807 }
808 os_name = os_name.toLowerCase();
809 os_arch = os_arch.toLowerCase();
810
811
812 File arch_lib_path = null;
813 String arch_libfile_suffix = null;
814
815
816
817 if (os_name.equals("linux") &&
818 (os_arch.equals("x86") || os_arch.equals("i386") ||
819 os_arch.equals("i486") || os_arch.equals("i586") || os_arch
820 .equals("i686"))) {
821 arch_lib_path = new File(new File(new File("lib"), "arch"),
822 "linux_x86");
823 arch_libfile_suffix = ".so";
824 }
825
826
827
828 else if (os_name.equals("linux") &&
829 os_arch.equals("amd64")) {
830 arch_lib_path = new File(new File(new File("lib"), "arch"), "linux_amd64");
831 arch_libfile_suffix = ".so";
832
833
834 } else if (os_name.startsWith("windows ") &&
835 (os_arch.equals("x86") || os_arch.equals("i386") ||
836 os_arch.equals("i486") || os_arch.equals("i586") || os_arch
837 .equals("i686"))) {
838 arch_lib_path = new File(new File(new File("lib"), "arch"),
839 "win32_x86");
840 arch_libfile_suffix = ".dll";
841 }
842
843
844
845 else if (os_name.startsWith("windows ") &&
846 os_arch.equals("amd64")) {
847 arch_lib_path = new File(new File(new File("lib"), "arch"), "win_amd64");
848 arch_libfile_suffix = ".dll";
849
850
851
852 } else if (os_name.startsWith("mac os x") && os_arch.equals("ppc")) {
853 arch_lib_path = new File(new File(new File("lib"), "arch"),
854 "darwin_ppc");
855 arch_libfile_suffix = ".jnilib";
856
857
858
859 }
860
861
862
863 else if (os_name.startsWith("mac os x") &&
864 (os_arch.equals("x86") ||
865 os_arch.equals("i386") ||
866 os_arch.equals("i486") ||
867 os_arch.equals("i586") ||
868 os_arch.equals("i686"))) {
869 arch_lib_path = new File(new File(new File("lib"), "arch"), "darwin_x86");
870 arch_libfile_suffix = ".jnilib";
871 }
872
873
874
875 else if (os_name.startsWith("mac os x") &&
876 os_arch.equals("x86_64")) {
877 arch_lib_path = new File(new File(new File("lib"), "arch"), "darwin_x86_64");
878 arch_libfile_suffix = ".jnilib";
879 }
880
881
882
883 else if (os_name.equals("freebsd") &&
884 (os_arch.equals("x86") ||
885 os_arch.equals("i386") ||
886 os_arch.equals("i486") ||
887 os_arch.equals("i586") ||
888 os_arch.equals("i686"))) {
889 arch_lib_path = new File(new File(new File("lib"), "arch"), "freebsd_x86");
890 arch_libfile_suffix = ".so";
891 }
892
893
894
895 else if (os_name.equals("freebsd") &&
896 os_arch.equals("amd64")) {
897 arch_lib_path = new File(new File(new File("lib"), "arch"), "freebsd_amd64");
898 arch_libfile_suffix = ".so";
899
900 } else {
901 arch_libfile_suffix = ".so";
902 }
903
904
905 String fname = "MD5" + arch_libfile_suffix;
906
907
908
909 if (arch_lib_path != null) {
910 f = new File(arch_lib_path, fname);
911 if (f.canRead()) {
912 System.load(f.getAbsolutePath());
913 return true;
914 }
915 }
916
917
918 f = new File(new File("lib"), fname);
919 if (f.canRead()) {
920 System.load(f.getAbsolutePath());
921 return true;
922 }
923
924
925 f = new File(fname);
926 if (f.canRead()) {
927 System.load(f.getAbsolutePath());
928 return true;
929 }
930
931
932
933 } catch (SecurityException e) {
934 System.err.println("Can't do native library: " + e.getMessage());
935 } catch (Exception e) {
936 System.err.println("Can't do native library: " + e.getMessage());
937 }
938
939
940
941 return false;
942 }
943
944
945
946
947
948
949
950
951
952 public static byte[] getHash(File f) throws IOException {
953 InputStream close_me = null;
954 try {
955 long buf_size = f.length();
956 if (buf_size < 512) {
957 buf_size = 512;
958 }
959 if (buf_size > 65536) {
960 buf_size = 65536;
961 }
962 byte[] buf = new byte[(int) buf_size];
963 FileInputStream in = new FileInputStream(f);
964 close_me = in;
965 MD5 md5 = new MD5();
966 int read = 0;
967 while ((read = in.read(buf)) >= 0) {
968 md5.Update(md5.state, buf, 0, read);
969 }
970 in.close();
971 in = null;
972 close_me = null;
973 buf = null;
974 buf = md5.Final();
975 return buf;
976 } catch (IOException e) {
977 if (close_me != null) {
978 try {
979 close_me.close();
980 } catch (Exception e2) {
981 }
982 }
983 throw e;
984 }
985 }
986
987
988
989
990
991
992
993
994
995
996 public static byte[] getHashNio(File f) throws IOException {
997 if (!f.exists()) {
998 throw new FileNotFoundException(f.toString());
999 }
1000 InputStream close_me = null;
1001 try {
1002 long buf_size = f.length();
1003 if (buf_size < 512) {
1004 buf_size = 512;
1005 }
1006 if (buf_size > 65536) {
1007 buf_size = 65536;
1008 }
1009 byte[] buf = new byte[(int) buf_size];
1010 FileInputStream in = new FileInputStream(f);
1011 close_me = in;
1012 FileChannel fileChannel = in.getChannel();
1013 ByteBuffer bb = ByteBuffer.wrap(buf);
1014 int read = 0;
1015 MD5 md5 = new MD5();
1016 read = fileChannel.read(bb);
1017 while (read > 0) {
1018 md5.Update(md5.state, buf, 0, read);
1019 bb.clear();
1020 read = fileChannel.read(bb);
1021 }
1022 fileChannel.close();
1023 fileChannel = null;
1024 in = null;
1025 close_me = null;
1026 bb = null;
1027 buf = null;
1028 buf = md5.Final();
1029 md5 = null;
1030 return buf;
1031 } catch (IOException e) {
1032 if (close_me != null) {
1033 try {
1034 close_me.close();
1035 } catch (Exception e2) {
1036 }
1037 }
1038 throw e;
1039 }
1040 }
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051 public static byte[] getHash(InputStream stream) throws IOException {
1052 try {
1053 long buf_size = 65536;
1054 byte[] buf = new byte[(int) buf_size];
1055 MD5 md5 = new MD5();
1056 int read = 0;
1057 while ((read = stream.read(buf)) >= 0) {
1058 md5.Update(md5.state, buf, 0, read);
1059 }
1060 stream.close();
1061 buf = null;
1062 buf = md5.Final();
1063 return buf;
1064 } catch (IOException e) {
1065 if (stream != null) {
1066 try {
1067 stream.close();
1068 } catch (Exception e2) {
1069 }
1070 }
1071 throw e;
1072 }
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 public static boolean hashesEqual(byte[] hash1, byte[] hash2) {
1086 return Arrays.equals(hash1, hash2);
1087 }
1088
1089 private static byte[] salt = {'G','o','l','d','e','n','G','a','t','e'};
1090
1091
1092
1093
1094
1095 public static final String passwdCrypt(String pwd) {
1096 MD5 md5 = new MD5();
1097 byte [] bpwd = pwd.getBytes();
1098 for (int i = 0; i < 16; i++) {
1099 md5.Update(md5.state, bpwd, 0, bpwd.length);
1100 md5.Update(md5.state, salt, 0, salt.length);
1101 }
1102 return md5.asHex();
1103 }
1104
1105
1106
1107
1108
1109 public static final byte[] passwdCrypt(byte[] bpwd) {
1110 MD5 md5 = new MD5();
1111 for (int i = 0; i < 16; i++) {
1112 md5.Update(md5.state, bpwd, 0, bpwd.length);
1113 md5.Update(md5.state, salt, 0, salt.length);
1114 }
1115 return md5.Final();
1116 }
1117
1118
1119
1120
1121
1122
1123 public static final boolean equalPasswd(String pwd, String cryptPwd){
1124 String asHex = passwdCrypt(pwd);
1125 return cryptPwd.equals(asHex);
1126 }
1127
1128
1129
1130
1131
1132
1133 public static final boolean equalPasswd(byte[] pwd, byte[] cryptPwd){
1134 byte [] bytes = passwdCrypt(pwd);
1135 return Arrays.equals(cryptPwd, bytes);
1136 }
1137
1138
1139
1140
1141
1142
1143
1144 public static void main(String argv[]) {
1145 long start = System.currentTimeMillis();
1146 if (argv.length < 1) {
1147
1148 boolean nativeLib = false;
1149
1150 nativeLib = initNativeLibrary(true);
1151 if (!nativeLib) {
1152 System.err.println("Native library cannot be load from " +
1153 "D:\\NEWJARS\\gglib\\win32\\MD5.dll");
1154 } else {
1155 System.out.println("Native library loaded from " + "D:\\NEWJARS\\gglib\\win32\\MD5.dll");
1156 }
1157 for (int i = 0; i < 1000000; i++) {
1158 passwdCrypt("Ceci est mon password!");
1159 }
1160 System.err.println("Final passwd crypted in "+(System.currentTimeMillis() - start)+"ms is: "+passwdCrypt("Ceci est mon password!"));
1161 System.err
1162 .println("Not enough argument: <full path to the filename to hash> [<full path to the native library>]");
1163 return;
1164 }
1165 boolean nativeLib = false;
1166 if (argv.length == 2) {
1167 nativeLib = initNativeLibrary(argv[1]);
1168 if (!nativeLib) {
1169 System.err.println("Native library cannot be load from " +
1170 argv[1]);
1171 } else {
1172 System.out.println("Native library loaded from " + argv[1]);
1173 }
1174 }
1175 File file = new File(argv[0]);
1176 byte[] bmd5;
1177 try {
1178
1179
1180 bmd5 = getHashNio(file);
1181
1182 } catch (IOException e1) {
1183 bmd5 = null;
1184 }
1185 if (bmd5 != null) {
1186 if (nativeLib) {
1187 System.out.println("FileInterface MD5 is " + asHex(bmd5) +
1188 " using Native Library in " +
1189 (System.currentTimeMillis() - start) + " ms");
1190 } else {
1191 System.out.println("FileInterface MD5 is " + asHex(bmd5) +
1192 " using Java version in " +
1193 (System.currentTimeMillis() - start) + " ms");
1194 }
1195 } else {
1196 System.err.println("Cannot compute md5 for " + argv[1]);
1197 }
1198 }
1199 }