001    package railo.runtime.crypt;
002    
003    public final class UnixCrypt extends Object { // 
004        // Null constructor - can't instantiate class private UnixCrypt() { } 
005        private static final char[] saltChars = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./".toCharArray()); 
006        private static final int ITERATIONS = 16; 
007        private static final int con_salt[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
008                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
009                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 
010                0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 
011                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 
012                0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 
013                0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x00, 0x00, 0x00, 0x00, 
014                0x00, }; 
015        private static final boolean shifts2[] = { false, false, true, true, true, true, true, true, false, true, true, true, true, 
016                true, true, false }; 
017        
018        private static final int skb[][] = { {0x00000000, 0x00000010, 0x20000000, 0x20000010, 0x00010000, 0x00010010, 0x20010000, 
019            0x20010010, 0x00000800, 0x00000810, 0x20000800, 0x20000810, 0x00010800, 0x00010810, 0x20010800, 0x20010810, 0x00000020, 
020            0x00000030, 0x20000020, 0x20000030, 0x00010020, 0x00010030, 0x20010020, 0x20010030, 0x00000820, 0x00000830, 0x20000820, 
021            0x20000830, 0x00010820, 0x00010830, 0x20010820, 0x20010830, 0x00080000, 0x00080010, 0x20080000, 0x20080010, 0x00090000, 
022            0x00090010, 0x20090000, 0x20090010, 0x00080800, 0x00080810, 0x20080800, 0x20080810, 0x00090800, 0x00090810, 0x20090800, 
023            0x20090810, 0x00080020, 0x00080030, 0x20080020, 0x20080030, 0x00090020, 0x00090030, 0x20090020, 0x20090030, 0x00080820, 
024            0x00080830, 0x20080820, 0x20080830, 0x00090820, 0x00090830, 0x20090820, 0x20090830, }, 
025            { /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ 0x00000000, 0x02000000, 0x00002000, 0x02002000, 0x00200000, 
026            0x02200000, 0x00202000, 0x02202000, 0x00000004, 0x02000004, 0x00002004, 0x02002004, 0x00200004, 0x02200004, 
027            0x00202004, 0x02202004, 0x00000400, 0x02000400, 0x00002400, 0x02002400, 0x00200400, 0x02200400, 0x00202400, 
028            0x02202400, 0x00000404, 0x02000404, 0x00002404, 0x02002404, 0x00200404, 0x02200404, 0x00202404, 0x02202404, 
029            0x10000000, 0x12000000, 0x10002000, 0x12002000, 0x10200000, 0x12200000, 0x10202000, 0x12202000, 0x10000004, 
030            0x12000004, 0x10002004, 0x12002004, 0x10200004, 0x12200004, 0x10202004, 0x12202004, 0x10000400, 0x12000400, 
031            0x10002400, 0x12002400, 0x10200400, 0x12200400, 0x10202400, 0x12202400, 0x10000404, 0x12000404, 0x10002404, 
032            0x12002404, 0x10200404, 0x12200404, 0x10202404, 0x12202404, }, 
033            { /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ 0x00000000, 0x00000001, 0x00040000, 0x00040001, 
034            0x01000000, 0x01000001, 0x01040000, 0x01040001, 0x00000002, 0x00000003, 0x00040002, 0x00040003, 0x01000002, 
035            0x01000003, 0x01040002, 0x01040003, 0x00000200, 0x00000201, 0x00040200, 0x00040201, 0x01000200, 0x01000201, 
036            0x01040200, 0x01040201, 0x00000202, 0x00000203, 0x00040202, 0x00040203, 0x01000202, 0x01000203, 0x01040202, 
037            0x01040203, 0x08000000, 0x08000001, 0x08040000, 0x08040001, 0x09000000, 0x09000001, 0x09040000, 0x09040001, 
038            0x08000002, 0x08000003, 0x08040002, 0x08040003, 0x09000002, 0x09000003, 0x09040002, 0x09040003, 0x08000200, 
039            0x08000201, 0x08040200, 0x08040201, 0x09000200, 0x09000201, 0x09040200, 0x09040201, 0x08000202, 0x08000203, 
040            0x08040202, 0x08040203, 0x09000202, 0x09000203, 0x09040202, 0x09040203, }, 
041            { /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ 0x00000000, 0x00100000, 0x00000100, 0x00100100, 
042            0x00000008, 0x00100008, 0x00000108, 0x00100108, 0x00001000, 0x00101000, 0x00001100, 0x00101100, 0x00001008, 
043            0x00101008, 0x00001108, 0x00101108, 0x04000000, 0x04100000, 0x04000100, 0x04100100, 0x04000008, 0x04100008, 
044            0x04000108, 0x04100108, 0x04001000, 0x04101000, 0x04001100, 0x04101100, 0x04001008, 0x04101008, 0x04001108, 
045            0x04101108, 0x00020000, 0x00120000, 0x00020100, 0x00120100, 0x00020008, 0x00120008, 0x00020108, 0x00120108, 
046            0x00021000, 0x00121000, 0x00021100, 0x00121100, 0x00021008, 0x00121008, 0x00021108, 0x00121108, 0x04020000, 
047            0x04120000, 0x04020100, 0x04120100, 0x04020008, 0x04120008, 0x04020108, 0x04120108, 0x04021000, 0x04121000, 
048            0x04021100, 0x04121100, 0x04021008, 0x04121008, 0x04021108, 0x04121108, }, 
049            { /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ 0x00000000, 0x10000000, 0x00010000, 0x10010000, 0x00000004, 
050            0x10000004, 0x00010004, 0x10010004, 0x20000000, 0x30000000, 0x20010000, 0x30010000, 0x20000004, 0x30000004, 0x20010004, 
051            0x30010004, 0x00100000, 0x10100000, 0x00110000, 0x10110000, 0x00100004, 0x10100004, 0x00110004, 0x10110004, 0x20100000, 
052            0x30100000, 0x20110000, 0x30110000, 0x20100004, 0x30100004, 0x20110004, 0x30110004, 0x00001000, 0x10001000, 0x00011000, 
053            0x10011000, 0x00001004, 0x10001004, 0x00011004, 0x10011004, 0x20001000, 0x30001000, 0x20011000, 0x30011000, 0x20001004, 
054            0x30001004, 0x20011004, 0x30011004, 0x00101000, 0x10101000, 0x00111000, 0x10111000, 0x00101004, 0x10101004, 0x00111004, 
055            0x10111004, 0x20101000, 0x30101000, 0x20111000, 0x30111000, 0x20101004, 0x30101004, 0x20111004, 0x30111004, }, 
056            { /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ 0x00000000, 0x08000000, 0x00000008, 0x08000008, 0x00000400, 
057            0x08000400, 0x00000408, 0x08000408, 0x00020000, 0x08020000, 0x00020008, 0x08020008, 0x00020400, 0x08020400, 0x00020408, 
058            0x08020408, 0x00000001, 0x08000001, 0x00000009, 0x08000009, 0x00000401, 0x08000401, 0x00000409, 0x08000409, 0x00020001, 
059            0x08020001, 0x00020009, 0x08020009, 0x00020401, 0x08020401, 0x00020409, 0x08020409, 0x02000000, 0x0A000000, 0x02000008, 
060            0x0A000008, 0x02000400, 0x0A000400, 0x02000408, 0x0A000408, 0x02020000, 0x0A020000, 0x02020008, 0x0A020008, 0x02020400, 
061            0x0A020400, 0x02020408, 0x0A020408, 0x02000001, 0x0A000001, 0x02000009, 0x0A000009, 0x02000401, 0x0A000401, 0x02000409, 
062            0x0A000409, 0x02020001, 0x0A020001, 0x02020009, 0x0A020009, 0x02020401, 0x0A020401, 0x02020409, 0x0A020409, }, 
063            { /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ 0x00000000, 0x00000100, 0x00080000, 0x00080100, 
064            0x01000000, 0x01000100, 0x01080000, 0x01080100, 0x00000010, 0x00000110, 0x00080010, 0x00080110, 0x01000010, 
065            0x01000110, 0x01080010, 0x01080110, 0x00200000, 0x00200100, 0x00280000, 0x00280100, 0x01200000, 0x01200100, 
066            0x01280000, 0x01280100, 0x00200010, 0x00200110, 0x00280010, 0x00280110, 0x01200010, 0x01200110, 0x01280010, 
067            0x01280110, 0x00000200, 0x00000300, 0x00080200, 0x00080300, 0x01000200, 0x01000300, 0x01080200, 0x01080300, 
068            0x00000210, 0x00000310, 0x00080210, 0x00080310, 0x01000210, 0x01000310, 0x01080210, 0x01080310, 0x00200200, 
069            0x00200300, 0x00280200, 0x00280300, 0x01200200, 0x01200300, 0x01280200, 0x01280300, 0x00200210, 0x00200310, 
070            0x00280210, 0x00280310, 0x01200210, 0x01200310, 0x01280210, 0x01280310, }, 
071            { /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 
072            0x00000002, 0x04000002, 0x00040002, 0x04040002, 0x00002000, 0x04002000, 0x00042000, 0x04042000, 0x00002002, 
073            0x04002002, 0x00042002, 0x04042002, 0x00000020, 0x04000020, 0x00040020, 0x04040020, 0x00000022, 0x04000022, 
074            0x00040022, 0x04040022, 0x00002020, 0x04002020, 0x00042020, 0x04042020, 0x00002022, 0x04002022, 0x00042022, 
075            0x04042022, 0x00000800, 0x04000800, 0x00040800, 0x04040800, 0x00000802, 0x04000802, 0x00040802, 0x04040802, 
076            0x00002800, 0x04002800, 0x00042800, 0x04042800, 0x00002802, 0x04002802, 0x00042802, 0x04042802, 0x00000820, 
077            0x04000820, 0x00040820, 0x04040820, 0x00000822, 0x04000822, 0x00040822, 0x04040822, 0x00002820, 0x04002820, 
078            0x00042820, 0x04042820, 0x00002822, 0x04002822, 0x00042822, 0x04042822, }, }; 
079        private static final int SPtrans[][] = { { /* nibble 0 */ 0x00820200, 0x00020000, 0x80800000, 0x80820200, 0x00800000, 
080            0x80020200, 0x80020000, 0x80800000, 0x80020200, 0x00820200, 0x00820000, 0x80000200, 0x80800200, 0x00800000, 0x00000000, 
081            0x80020000, 0x00020000, 0x80000000, 0x00800200, 0x00020200, 0x80820200, 0x00820000, 0x80000200, 0x00800200, 0x80000000, 
082            0x00000200, 0x00020200, 0x80820000, 0x00000200, 0x80800200, 0x80820000, 0x00000000, 0x00000000, 0x80820200, 0x00800200, 
083            0x80020000, 0x00820200, 0x00020000, 0x80000200, 0x00800200, 0x80820000, 0x00000200, 0x00020200, 0x80800000, 0x80020200, 
084            0x80000000, 0x80800000, 0x00820000, 0x80820200, 0x00020200, 0x00820000, 0x80800200, 0x00800000, 0x80000200, 0x80020000, 
085            0x00000000, 0x00020000, 0x00800000, 0x80800200, 0x00820200, 0x80000000, 0x80820000, 0x00000200, 0x80020200, }, 
086            { /* nibble 1 */ 0x10042004, 0x00000000, 0x00042000, 0x10040000, 0x10000004, 0x00002004, 0x10002000, 0x00042000, 
087            0x00002000, 0x10040004, 0x00000004, 0x10002000, 0x00040004, 0x10042000, 0x10040000, 0x00000004, 0x00040000, 0x10002004, 
088            0x10040004, 0x00002000, 0x00042004, 0x10000000, 0x00000000, 0x00040004, 0x10002004, 0x00042004, 0x10042000, 0x10000004, 
089            0x10000000, 0x00040000, 0x00002004, 0x10042004, 0x00040004, 0x10042000, 0x10002000, 0x00042004, 0x10042004, 0x00040004, 
090            0x10000004, 0x00000000, 0x10000000, 0x00002004, 0x00040000, 0x10040004, 0x00002000, 0x10000000, 0x00042004, 0x10002004, 
091            0x10042000, 0x00002000, 0x00000000, 0x10000004, 0x00000004, 0x10042004, 0x00042000, 0x10040000, 0x10040004, 0x00040000, 
092            0x00002004, 0x10002000, 0x10002004, 0x00000004, 0x10040000, 0x00042000, }, { /* nibble 2 */ 0x41000000, 0x01010040, 
093            0x00000040, 0x41000040, 0x40010000, 0x01000000, 0x41000040, 0x00010040, 0x01000040, 0x00010000, 0x01010000, 0x40000000, 
094            0x41010040, 0x40000040, 0x40000000, 0x41010000, 0x00000000, 0x40010000, 0x01010040, 0x00000040, 0x40000040, 0x41010040, 
095            0x00010000, 0x41000000, 0x41010000, 0x01000040, 0x40010040, 0x01010000, 0x00010040, 0x00000000, 0x01000000, 0x40010040, 
096            0x01010040, 0x00000040, 0x40000000, 0x00010000, 0x40000040, 0x40010000, 0x01010000, 0x41000040, 0x00000000, 0x01010040, 
097            0x00010040, 0x41010000, 0x40010000, 0x01000000, 0x41010040, 0x40000000, 0x40010040, 0x41000000, 0x01000000, 0x41010040, 
098            0x00010000, 0x01000040, 0x41000040, 0x00010040, 0x01000040, 0x00000000, 0x41010000, 0x40000040, 0x41000000, 0x40010040, 
099            0x00000040, 0x01010000, }, { /* nibble 3 */ 0x00100402, 0x04000400, 0x00000002, 0x04100402, 0x00000000, 0x04100000, 
100            0x04000402, 0x00100002, 0x04100400, 0x04000002, 0x04000000, 0x00000402, 0x04000002, 0x00100402, 0x00100000, 0x04000000, 
101            0x04100002, 0x00100400, 0x00000400, 0x00000002, 0x00100400, 0x04000402, 0x04100000, 0x00000400, 0x00000402, 0x00000000, 
102            0x00100002, 0x04100400, 0x04000400, 0x04100002, 0x04100402, 0x00100000, 0x04100002, 0x00000402, 0x00100000, 0x04000002, 
103            0x00100400, 0x04000400, 0x00000002, 0x04100000, 0x04000402, 0x00000000, 0x00000400, 0x00100002, 0x00000000, 0x04100002, 
104            0x04100400, 0x00000400, 0x04000000, 0x04100402, 0x00100402, 0x00100000, 0x04100402, 0x00000002, 0x04000400, 0x00100402, 
105            0x00100002, 0x00100400, 0x04100000, 0x04000402, 0x00000402, 0x04000000, 0x04000002, 0x04100400, }, 
106            { /* nibble 4 */ 0x02000000, 0x00004000, 0x00000100, 0x02004108, 0x02004008, 0x02000100, 0x00004108, 0x02004000, 
107            0x00004000, 0x00000008, 0x02000008, 0x00004100, 0x02000108, 0x02004008, 0x02004100, 0x00000000, 0x00004100, 
108            0x02000000, 0x00004008, 0x00000108, 0x02000100, 0x00004108, 0x00000000, 0x02000008, 0x00000008, 0x02000108, 
109            0x02004108, 0x00004008, 0x02004000, 0x00000100, 0x00000108, 0x02004100, 0x02004100, 0x02000108, 0x00004008, 
110            0x02004000, 0x00004000, 0x00000008, 0x02000008, 0x02000100, 0x02000000, 0x00004100, 0x02004108, 0x00000000, 
111            0x00004108, 0x02000000, 0x00000100, 0x00004008, 0x02000108, 0x00000100, 0x00000000, 0x02004108, 0x02004008, 
112            0x02004100, 0x00000108, 0x00004000, 0x00004100, 0x02004008, 0x02000100, 0x00000108, 0x00000008, 0x00004108, 
113            0x02004000, 0x02000008, }, { /* nibble 5 */ 0x20000010, 0x00080010, 0x00000000, 0x20080800, 0x00080010, 
114            0x00000800, 0x20000810, 0x00080000, 0x00000810, 0x20080810, 0x00080800, 0x20000000, 0x20000800, 0x20000010, 
115            0x20080000, 0x00080810, 0x00080000, 0x20000810, 0x20080010, 0x00000000, 0x00000800, 0x00000010, 0x20080800, 
116            0x20080010, 0x20080810, 0x20080000, 0x20000000, 0x00000810, 0x00000010, 0x00080800, 0x00080810, 0x20000800, 
117            0x00000810, 0x20000000, 0x20000800, 0x00080810, 0x20080800, 0x00080010, 0x00000000, 0x20000800, 0x20000000, 
118            0x00000800, 0x20080010, 0x00080000, 0x00080010, 0x20080810, 0x00080800, 0x00000010, 0x20080810, 0x00080800, 
119            0x00080000, 0x20000810, 0x20000010, 0x20080000, 0x00080810, 0x00000000, 0x00000800, 0x20000010, 0x20000810, 
120            0x20080800, 0x20080000, 0x00000810, 0x00000010, 0x20080010, }, { /* nibble 6 */ 0x00001000, 0x00000080, 
121            0x00400080, 0x00400001, 0x00401081, 0x00001001, 0x00001080, 0x00000000, 0x00400000, 0x00400081, 0x00000081, 
122            0x00401000, 0x00000001, 0x00401080, 0x00401000, 0x00000081, 0x00400081, 0x00001000, 0x00001001, 0x00401081, 
123            0x00000000, 0x00400080, 0x00400001, 0x00001080, 0x00401001, 0x00001081, 0x00401080, 0x00000001, 0x00001081, 
124            0x00401001, 0x00000080, 0x00400000, 0x00001081, 0x00401000, 0x00401001, 0x00000081, 0x00001000, 0x00000080, 
125            0x00400000, 0x00401001, 0x00400081, 0x00001081, 0x00001080, 0x00000000, 0x00000080, 0x00400001, 0x00000001, 
126            0x00400080, 0x00000000, 0x00400081, 0x00400080, 0x00001080, 0x00000081, 0x00001000, 0x00401081, 0x00400000, 
127            0x00401080, 0x00000001, 0x00001001, 0x00401081, 0x00400001, 0x00401080, 0x00401000, 0x00001001, }, 
128            { /* nibble 7 */ 0x08200020, 0x08208000, 0x00008020, 0x00000000, 0x08008000, 0x00200020, 0x08200000, 0x08208020, 
129            0x00000020, 0x08000000, 0x00208000, 0x00008020, 0x00208020, 0x08008020, 0x08000020, 0x08200000, 0x00008000, 
130            0x00208020, 0x00200020, 0x08008000, 0x08208020, 0x08000020, 0x00000000, 0x00208000, 0x08000000, 0x00200000, 
131            0x08008020, 0x08200020, 0x00200000, 0x00008000, 0x08208000, 0x00000020, 0x00200000, 0x00008000, 0x08000020, 
132            0x08208020, 0x00008020, 0x08000000, 0x00000000, 0x00208000, 0x08200020, 0x08008020, 0x08008000, 0x00200020, 
133            0x08208000, 0x00000020, 0x00200020, 0x08008000, 0x08208020, 0x00200000, 0x08200000, 0x08000020, 0x00208000, 
134            0x00008020, 0x08008020, 0x08200000, 0x00000020, 0x08208000, 0x00208020, 0x00000000, 0x08000000, 0x08200020, 
135            0x00008000, 0x00208020 } }; 
136        private static final int cov_2char[] = { 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 
137            0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 
138            0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 
139            0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A }; 
140        private static final int byteToUnsigned(byte b) { int value = b; return(value >= 0 ? value : value + 256); } 
141        private static int fourBytesToInt(byte b[], int offset) { int value; value = byteToUnsigned(b[offset++]); 
142        value |= (byteToUnsigned(b[offset++]) << 8); 
143        value |= (byteToUnsigned(b[offset++]) << 16); 
144        value |= (byteToUnsigned(b[offset++]) << 24); 
145        return(value); } 
146        private static final void intToFourBytes(int iValue, byte b[], int offset) { 
147            b[offset++] = (byte)((iValue) & 0xff); 
148            b[offset++] = (byte)((iValue >>> 8 ) & 0xff); 
149            b[offset++] = (byte)((iValue >>> 16) & 0xff); 
150            b[offset++] = (byte)((iValue >>> 24) & 0xff); 
151        } 
152        private static final void PERM_OP(int a, int b, int n, int m, int results[]) { 
153            int t; t = ((a >>> n) ^ b) & m; a ^= t << n; b ^= t; results[0] = a; results[1] = b; 
154        } 
155        private static final int HPERM_OP(int a, int n, int m) { 
156            int t; t = ((a << (16 - n)) ^ a) & m; 
157            a = a ^ t ^ (t >>> (16 - n)); 
158            return(a); 
159        } 
160        private static int [] des_set_key(byte key[]) { 
161            int schedule[] = new int[ITERATIONS * 2]; 
162            int c = fourBytesToInt(key, 0); 
163            int d = fourBytesToInt(key, 4); 
164            int results[] = new int[2]; 
165            PERM_OP(d, c, 4, 0x0f0f0f0f, results); 
166            d = results[0]; 
167            c = results[1]; 
168            c = HPERM_OP(c, -2, 0xcccc0000); 
169            d = HPERM_OP(d, -2, 0xcccc0000); 
170            PERM_OP(d, c, 1, 0x55555555, results); 
171            d = results[0]; c = results[1]; 
172            PERM_OP(c, d, 8, 0x00ff00ff, results); 
173            c = results[0]; d = results[1]; 
174            PERM_OP(d, c, 1, 0x55555555, results); 
175            d = results[0]; c = results[1]; 
176            d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) | ((d & 0x00ff0000) >>> 16) | ((c & 0xf0000000) >>> 4)); 
177            c &= 0x0fffffff; 
178            int s, t;
179            int j = 0; 
180            for(int i = 0; i < ITERATIONS; i ++) { 
181                if(shifts2[i]) { 
182                    c = (c >>> 2) | (c << 26); 
183                    d = (d >>> 2) | (d << 26); 
184                } 
185                else { 
186                    c = (c >>> 1) | (c << 27); 
187                    d = (d >>> 1) | (d << 27); 
188                } 
189                c &= 0x0fffffff; 
190                d &= 0x0fffffff; 
191                s = skb[0][ (c ) & 0x3f ]| skb[1][((c >>> 6) & 0x03) | ((c >>> 7) & 0x3c)]| skb[2][((c >>> 13) & 0x0f) | 
192                       ((c >>> 14) & 0x30)]| skb[3][((c >>> 20) & 0x01) | ((c >>> 21) & 0x06) | ((c >>> 22) & 0x38)]; 
193                t = skb[4][ (d ) & 0x3f ]| skb[5][((d >>> 7) & 0x03) | ((d >>> 8) & 0x3c)]| skb[6][ (d >>>15) & 0x3f ]| 
194                            skb[7][((d >>>21) & 0x0f) | ((d >>> 22) & 0x30)]; schedule[j++] = ((t << 16) | (s & 0x0000ffff)) 
195                            & 0xffffffff; s = ((s >>> 16) | (t & 0xffff0000)); s = (s << 4) | (s >>> 28); 
196                schedule[j++] = s & 0xffffffff; 
197            } 
198            return(schedule); 
199        } 
200        private static final int D_ENCRYPT ( int L, int R, int S, int E0, int E1, int s[] ) { 
201            int t, u, v; v = R ^ (R >>> 16); 
202            u = v & E0; v = v & E1; 
203            u = (u ^ (u << 16)) ^ R ^ s[S]; 
204            t = (v ^ (v << 16)) ^ R ^ s[S + 1]; 
205            t = (t >>> 4) | (t << 28); 
206            L ^= SPtrans[1][(t ) & 0x3f] | SPtrans[3][(t >>> 8) & 0x3f] | SPtrans[5][(t >>> 16) & 0x3f] | SPtrans[7][(t >>> 24) 
207                     & 0x3f] | SPtrans[0][(u ) & 0x3f] | SPtrans[2][(u >>> 8) & 0x3f] | SPtrans[4][(u >>> 16) & 0x3f] | 
208                     SPtrans[6][(u >>> 24) & 0x3f]; return(L); 
209       } 
210       private static final int [] body(int schedule[], int Eswap0, int Eswap1) { 
211           int left = 0; 
212           int right = 0; 
213           int t = 0; 
214           for(int j = 0; j < 25; j ++) { 
215               for(int i = 0; i < ITERATIONS * 2; i += 4) { 
216                   left = D_ENCRYPT(left, right, i, Eswap0, Eswap1, schedule); 
217                   right = D_ENCRYPT(right, left, i + 2, Eswap0, Eswap1, schedule); 
218               } 
219               t = left; 
220               left = right; 
221               right = t; 
222          } 
223          t = right; 
224          right = (left >>> 1) | (left << 31); 
225          left = (t >>> 1) | (t << 31); 
226          left &= 0xffffffff; right &= 0xffffffff; 
227          int results[] = new int[2]; 
228          PERM_OP(right, left, 1, 0x55555555, results); 
229          right = results[0]; 
230          left = results[1]; 
231          PERM_OP(left, right, 8, 0x00ff00ff, results); 
232          left = results[0]; right = results[1]; 
233          PERM_OP(right, left, 2, 0x33333333, results); 
234          right = results[0]; left = results[1]; 
235          PERM_OP(left, right, 16, 0x0000ffff, results); 
236          left = results[0]; right = results[1]; 
237          PERM_OP(right, left, 4, 0x0f0f0f0f, results); 
238          right = results[0]; 
239          left = results[1]; 
240          int out[] = new int[2]; 
241          out[0] = left; 
242          out[1] = right; 
243          return(out); 
244       } 
245       /** * 
246       Encrypt a password given the cleartext password and a "salt".
247       * @param salt A two-character string representing the salt used to 
248       * iterate the encryption engine in lots of different ways. If you 
249       * are generating a new encryption then this value should be 
250       * randomised. 
251       * @param original The password to be encrypted. 
252       * @return A string consisting of the 2-character salt followed by the 
253       * encrypted password. 
254       */ 
255       public static final String crypt(String salt, String original) { 
256           while(salt.length() < 2) salt += "A"; 
257           StringBuffer buffer = new StringBuffer(" "); 
258           char charZero = salt.charAt(0); 
259           char charOne = salt.charAt(1); 
260           buffer.setCharAt(0, charZero); 
261           buffer.setCharAt(1, charOne); 
262           int Eswap0 = con_salt[charZero]; 
263           int Eswap1 = con_salt[charOne] << 4; byte key[] = new byte[8]; 
264           for(int i = 0; i < key.length; i ++) key[i] = (byte)0; 
265           for(int i = 0; i < key.length && i < original.length(); i ++) { 
266               int iChar = original.charAt(i); 
267               key[i] = (byte)(iChar << 1); 
268           } 
269           int schedule[] = des_set_key(key); 
270           int out[] = body(schedule, Eswap0, Eswap1); 
271           byte b[] = new byte[9]; 
272           intToFourBytes(out[0], b, 0); 
273           intToFourBytes(out[1], b, 4); 
274           b[8] = 0; for(int i = 2, y = 0, u = 0x80; i < 13; i ++) { 
275               for(int j = 0, c = 0; j < 6; j ++) { 
276                   c <<= 1; 
277                   if((b[y] & u) != 0) c |= 1; 
278                   u >>>= 1; if(u == 0) { y++; u = 0x80; } 
279                   buffer.setCharAt(i, (char)cov_2char[c]);
280               } 
281           } 
282           return(buffer.toString()); 
283      } 
284       /** 
285            Encrypt a password given the cleartext password. This method 
286      * generates a random salt using the 'java.util.Random' class.
287      * 
288            * @param original The password to be encrypted. 
289            * @return A string consisting of the 2-character salt followed by the 
290            * encrypted password. */ 
291       public static final String crypt(String original) { 
292           java.util.Random randomGenerator = new java.util.Random(); 
293           int numSaltChars = saltChars.length; String salt; 
294           salt = (new StringBuffer()).append(saltChars[Math.abs(randomGenerator.nextInt()) % numSaltChars]).
295           append(saltChars[Math.abs(randomGenerator.nextInt()) % numSaltChars]).toString(); 
296           return crypt(salt, original); 
297       } 
298       /** * 
299        Check that enteredPassword encrypts to * encryptedPassword.
300        * @param encryptedPassword The encryptedPassword. The first 
301        * two characters are assumed to be the salt. This string would 
302        * be the same as one found in a Unix /etc/passwd file. 
303        * @param enteredPassword The password as entered by the user (or 
304        * otherwise aquired). 
305        * @return true if the password should be considered correct. */ 
306       public final static boolean matches(String encryptedPassword, String enteredPassword) { 
307           String salt = encryptedPassword.substring(0, 3); 
308           String newCrypt = crypt(salt, enteredPassword); 
309           return newCrypt.equals(encryptedPassword); 
310       } 
311    }