001    package org.rakeshv.utils;
002    
003    /**
004     * Pure Java implementation of the UNIX crypt library.  Source code
005     * <a href='http://locutus.kingwoodcable.com/jfd/crypt.html'>from</a>.
006     */
007    public class JCrypt
008    {
009       private JCrypt() {}
010    
011       private static final int ITERATIONS = 16;
012    
013       private static final int con_salt[] =
014       {
015          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
016          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
017          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
018          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
019          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
020          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
021          0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
022          0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 
023          0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 
024          0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 
025          0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 
026          0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, 
027          0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 
028          0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 
029          0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 
030          0x3D, 0x3E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 
031       };
032    
033       private static final boolean shifts2[] =
034       {
035          false, false, true, true, true, true, true, true,
036          false, true,  true, true, true, true, true, false
037       };
038    
039       private static final int skb[][] =
040       {
041          {
042             /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
043             0x00000000, 0x00000010, 0x20000000, 0x20000010, 
044             0x00010000, 0x00010010, 0x20010000, 0x20010010, 
045             0x00000800, 0x00000810, 0x20000800, 0x20000810, 
046             0x00010800, 0x00010810, 0x20010800, 0x20010810, 
047             0x00000020, 0x00000030, 0x20000020, 0x20000030, 
048             0x00010020, 0x00010030, 0x20010020, 0x20010030, 
049             0x00000820, 0x00000830, 0x20000820, 0x20000830, 
050             0x00010820, 0x00010830, 0x20010820, 0x20010830, 
051             0x00080000, 0x00080010, 0x20080000, 0x20080010, 
052             0x00090000, 0x00090010, 0x20090000, 0x20090010, 
053             0x00080800, 0x00080810, 0x20080800, 0x20080810, 
054             0x00090800, 0x00090810, 0x20090800, 0x20090810, 
055             0x00080020, 0x00080030, 0x20080020, 0x20080030, 
056             0x00090020, 0x00090030, 0x20090020, 0x20090030, 
057             0x00080820, 0x00080830, 0x20080820, 0x20080830, 
058             0x00090820, 0x00090830, 0x20090820, 0x20090830, 
059          },
060          {
061             /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
062             0x00000000, 0x02000000, 0x00002000, 0x02002000, 
063             0x00200000, 0x02200000, 0x00202000, 0x02202000, 
064             0x00000004, 0x02000004, 0x00002004, 0x02002004, 
065             0x00200004, 0x02200004, 0x00202004, 0x02202004, 
066             0x00000400, 0x02000400, 0x00002400, 0x02002400, 
067             0x00200400, 0x02200400, 0x00202400, 0x02202400, 
068             0x00000404, 0x02000404, 0x00002404, 0x02002404, 
069             0x00200404, 0x02200404, 0x00202404, 0x02202404, 
070             0x10000000, 0x12000000, 0x10002000, 0x12002000, 
071             0x10200000, 0x12200000, 0x10202000, 0x12202000, 
072             0x10000004, 0x12000004, 0x10002004, 0x12002004, 
073             0x10200004, 0x12200004, 0x10202004, 0x12202004, 
074             0x10000400, 0x12000400, 0x10002400, 0x12002400, 
075             0x10200400, 0x12200400, 0x10202400, 0x12202400, 
076             0x10000404, 0x12000404, 0x10002404, 0x12002404, 
077             0x10200404, 0x12200404, 0x10202404, 0x12202404, 
078          },
079          {
080             /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
081             0x00000000, 0x00000001, 0x00040000, 0x00040001, 
082             0x01000000, 0x01000001, 0x01040000, 0x01040001, 
083             0x00000002, 0x00000003, 0x00040002, 0x00040003, 
084             0x01000002, 0x01000003, 0x01040002, 0x01040003, 
085             0x00000200, 0x00000201, 0x00040200, 0x00040201, 
086             0x01000200, 0x01000201, 0x01040200, 0x01040201, 
087             0x00000202, 0x00000203, 0x00040202, 0x00040203, 
088             0x01000202, 0x01000203, 0x01040202, 0x01040203, 
089             0x08000000, 0x08000001, 0x08040000, 0x08040001, 
090             0x09000000, 0x09000001, 0x09040000, 0x09040001, 
091             0x08000002, 0x08000003, 0x08040002, 0x08040003, 
092             0x09000002, 0x09000003, 0x09040002, 0x09040003, 
093             0x08000200, 0x08000201, 0x08040200, 0x08040201, 
094             0x09000200, 0x09000201, 0x09040200, 0x09040201, 
095             0x08000202, 0x08000203, 0x08040202, 0x08040203, 
096             0x09000202, 0x09000203, 0x09040202, 0x09040203, 
097          },
098          {
099             /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
100             0x00000000, 0x00100000, 0x00000100, 0x00100100, 
101             0x00000008, 0x00100008, 0x00000108, 0x00100108, 
102             0x00001000, 0x00101000, 0x00001100, 0x00101100, 
103             0x00001008, 0x00101008, 0x00001108, 0x00101108, 
104             0x04000000, 0x04100000, 0x04000100, 0x04100100, 
105             0x04000008, 0x04100008, 0x04000108, 0x04100108, 
106             0x04001000, 0x04101000, 0x04001100, 0x04101100, 
107             0x04001008, 0x04101008, 0x04001108, 0x04101108, 
108             0x00020000, 0x00120000, 0x00020100, 0x00120100, 
109             0x00020008, 0x00120008, 0x00020108, 0x00120108, 
110             0x00021000, 0x00121000, 0x00021100, 0x00121100, 
111             0x00021008, 0x00121008, 0x00021108, 0x00121108, 
112             0x04020000, 0x04120000, 0x04020100, 0x04120100, 
113             0x04020008, 0x04120008, 0x04020108, 0x04120108, 
114             0x04021000, 0x04121000, 0x04021100, 0x04121100, 
115             0x04021008, 0x04121008, 0x04021108, 0x04121108, 
116          },
117          {
118             /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
119             0x00000000, 0x10000000, 0x00010000, 0x10010000, 
120             0x00000004, 0x10000004, 0x00010004, 0x10010004, 
121             0x20000000, 0x30000000, 0x20010000, 0x30010000, 
122             0x20000004, 0x30000004, 0x20010004, 0x30010004, 
123             0x00100000, 0x10100000, 0x00110000, 0x10110000, 
124             0x00100004, 0x10100004, 0x00110004, 0x10110004, 
125             0x20100000, 0x30100000, 0x20110000, 0x30110000, 
126             0x20100004, 0x30100004, 0x20110004, 0x30110004, 
127             0x00001000, 0x10001000, 0x00011000, 0x10011000, 
128             0x00001004, 0x10001004, 0x00011004, 0x10011004, 
129             0x20001000, 0x30001000, 0x20011000, 0x30011000, 
130             0x20001004, 0x30001004, 0x20011004, 0x30011004, 
131             0x00101000, 0x10101000, 0x00111000, 0x10111000, 
132             0x00101004, 0x10101004, 0x00111004, 0x10111004, 
133             0x20101000, 0x30101000, 0x20111000, 0x30111000, 
134             0x20101004, 0x30101004, 0x20111004, 0x30111004, 
135          },
136          {
137             /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
138             0x00000000, 0x08000000, 0x00000008, 0x08000008, 
139             0x00000400, 0x08000400, 0x00000408, 0x08000408, 
140             0x00020000, 0x08020000, 0x00020008, 0x08020008, 
141             0x00020400, 0x08020400, 0x00020408, 0x08020408, 
142             0x00000001, 0x08000001, 0x00000009, 0x08000009, 
143             0x00000401, 0x08000401, 0x00000409, 0x08000409, 
144             0x00020001, 0x08020001, 0x00020009, 0x08020009, 
145             0x00020401, 0x08020401, 0x00020409, 0x08020409, 
146             0x02000000, 0x0A000000, 0x02000008, 0x0A000008, 
147             0x02000400, 0x0A000400, 0x02000408, 0x0A000408, 
148             0x02020000, 0x0A020000, 0x02020008, 0x0A020008, 
149             0x02020400, 0x0A020400, 0x02020408, 0x0A020408, 
150             0x02000001, 0x0A000001, 0x02000009, 0x0A000009, 
151             0x02000401, 0x0A000401, 0x02000409, 0x0A000409, 
152             0x02020001, 0x0A020001, 0x02020009, 0x0A020009, 
153             0x02020401, 0x0A020401, 0x02020409, 0x0A020409, 
154          },
155          {
156             /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
157             0x00000000, 0x00000100, 0x00080000, 0x00080100, 
158             0x01000000, 0x01000100, 0x01080000, 0x01080100, 
159             0x00000010, 0x00000110, 0x00080010, 0x00080110, 
160             0x01000010, 0x01000110, 0x01080010, 0x01080110, 
161             0x00200000, 0x00200100, 0x00280000, 0x00280100, 
162             0x01200000, 0x01200100, 0x01280000, 0x01280100, 
163             0x00200010, 0x00200110, 0x00280010, 0x00280110, 
164             0x01200010, 0x01200110, 0x01280010, 0x01280110, 
165             0x00000200, 0x00000300, 0x00080200, 0x00080300, 
166             0x01000200, 0x01000300, 0x01080200, 0x01080300, 
167             0x00000210, 0x00000310, 0x00080210, 0x00080310, 
168             0x01000210, 0x01000310, 0x01080210, 0x01080310, 
169             0x00200200, 0x00200300, 0x00280200, 0x00280300, 
170             0x01200200, 0x01200300, 0x01280200, 0x01280300, 
171             0x00200210, 0x00200310, 0x00280210, 0x00280310, 
172             0x01200210, 0x01200310, 0x01280210, 0x01280310, 
173          },
174          {
175             /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
176             0x00000000, 0x04000000, 0x00040000, 0x04040000, 
177             0x00000002, 0x04000002, 0x00040002, 0x04040002, 
178             0x00002000, 0x04002000, 0x00042000, 0x04042000, 
179             0x00002002, 0x04002002, 0x00042002, 0x04042002, 
180             0x00000020, 0x04000020, 0x00040020, 0x04040020, 
181             0x00000022, 0x04000022, 0x00040022, 0x04040022, 
182             0x00002020, 0x04002020, 0x00042020, 0x04042020, 
183             0x00002022, 0x04002022, 0x00042022, 0x04042022, 
184             0x00000800, 0x04000800, 0x00040800, 0x04040800, 
185             0x00000802, 0x04000802, 0x00040802, 0x04040802, 
186             0x00002800, 0x04002800, 0x00042800, 0x04042800, 
187             0x00002802, 0x04002802, 0x00042802, 0x04042802, 
188             0x00000820, 0x04000820, 0x00040820, 0x04040820, 
189             0x00000822, 0x04000822, 0x00040822, 0x04040822, 
190             0x00002820, 0x04002820, 0x00042820, 0x04042820, 
191             0x00002822, 0x04002822, 0x00042822, 0x04042822, 
192          },
193       };
194    
195       private static final int SPtrans[][] =
196       {
197          {
198             /* nibble 0 */
199             0x00820200, 0x00020000, 0x80800000, 0x80820200,
200             0x00800000, 0x80020200, 0x80020000, 0x80800000,
201             0x80020200, 0x00820200, 0x00820000, 0x80000200,
202             0x80800200, 0x00800000, 0x00000000, 0x80020000,
203             0x00020000, 0x80000000, 0x00800200, 0x00020200,
204             0x80820200, 0x00820000, 0x80000200, 0x00800200,
205             0x80000000, 0x00000200, 0x00020200, 0x80820000,
206             0x00000200, 0x80800200, 0x80820000, 0x00000000,
207             0x00000000, 0x80820200, 0x00800200, 0x80020000,
208             0x00820200, 0x00020000, 0x80000200, 0x00800200,
209             0x80820000, 0x00000200, 0x00020200, 0x80800000,
210             0x80020200, 0x80000000, 0x80800000, 0x00820000,
211             0x80820200, 0x00020200, 0x00820000, 0x80800200,
212             0x00800000, 0x80000200, 0x80020000, 0x00000000,
213             0x00020000, 0x00800000, 0x80800200, 0x00820200,
214             0x80000000, 0x80820000, 0x00000200, 0x80020200,
215          },
216          {
217             /* nibble 1 */
218             0x10042004, 0x00000000, 0x00042000, 0x10040000,
219             0x10000004, 0x00002004, 0x10002000, 0x00042000,
220             0x00002000, 0x10040004, 0x00000004, 0x10002000,
221             0x00040004, 0x10042000, 0x10040000, 0x00000004,
222             0x00040000, 0x10002004, 0x10040004, 0x00002000,
223             0x00042004, 0x10000000, 0x00000000, 0x00040004,
224             0x10002004, 0x00042004, 0x10042000, 0x10000004,
225             0x10000000, 0x00040000, 0x00002004, 0x10042004,
226             0x00040004, 0x10042000, 0x10002000, 0x00042004,
227             0x10042004, 0x00040004, 0x10000004, 0x00000000,
228             0x10000000, 0x00002004, 0x00040000, 0x10040004,
229             0x00002000, 0x10000000, 0x00042004, 0x10002004,
230             0x10042000, 0x00002000, 0x00000000, 0x10000004,
231             0x00000004, 0x10042004, 0x00042000, 0x10040000,
232             0x10040004, 0x00040000, 0x00002004, 0x10002000,
233             0x10002004, 0x00000004, 0x10040000, 0x00042000,
234          },
235          {
236             /* nibble 2 */
237             0x41000000, 0x01010040, 0x00000040, 0x41000040,
238             0x40010000, 0x01000000, 0x41000040, 0x00010040,
239             0x01000040, 0x00010000, 0x01010000, 0x40000000,
240             0x41010040, 0x40000040, 0x40000000, 0x41010000,
241             0x00000000, 0x40010000, 0x01010040, 0x00000040,
242             0x40000040, 0x41010040, 0x00010000, 0x41000000,
243             0x41010000, 0x01000040, 0x40010040, 0x01010000,
244             0x00010040, 0x00000000, 0x01000000, 0x40010040,
245             0x01010040, 0x00000040, 0x40000000, 0x00010000,
246             0x40000040, 0x40010000, 0x01010000, 0x41000040,
247             0x00000000, 0x01010040, 0x00010040, 0x41010000,
248             0x40010000, 0x01000000, 0x41010040, 0x40000000,
249             0x40010040, 0x41000000, 0x01000000, 0x41010040,
250             0x00010000, 0x01000040, 0x41000040, 0x00010040,
251             0x01000040, 0x00000000, 0x41010000, 0x40000040,
252             0x41000000, 0x40010040, 0x00000040, 0x01010000,
253          },
254          {
255             /* nibble 3 */
256             0x00100402, 0x04000400, 0x00000002, 0x04100402,
257             0x00000000, 0x04100000, 0x04000402, 0x00100002,
258             0x04100400, 0x04000002, 0x04000000, 0x00000402,
259             0x04000002, 0x00100402, 0x00100000, 0x04000000,
260             0x04100002, 0x00100400, 0x00000400, 0x00000002,
261             0x00100400, 0x04000402, 0x04100000, 0x00000400,
262             0x00000402, 0x00000000, 0x00100002, 0x04100400,
263             0x04000400, 0x04100002, 0x04100402, 0x00100000,
264             0x04100002, 0x00000402, 0x00100000, 0x04000002,
265             0x00100400, 0x04000400, 0x00000002, 0x04100000,
266             0x04000402, 0x00000000, 0x00000400, 0x00100002,
267             0x00000000, 0x04100002, 0x04100400, 0x00000400,
268             0x04000000, 0x04100402, 0x00100402, 0x00100000,
269             0x04100402, 0x00000002, 0x04000400, 0x00100402,
270             0x00100002, 0x00100400, 0x04100000, 0x04000402,
271             0x00000402, 0x04000000, 0x04000002, 0x04100400,
272          },
273          {
274             /* nibble 4 */
275             0x02000000, 0x00004000, 0x00000100, 0x02004108,
276             0x02004008, 0x02000100, 0x00004108, 0x02004000,
277             0x00004000, 0x00000008, 0x02000008, 0x00004100,
278             0x02000108, 0x02004008, 0x02004100, 0x00000000,
279             0x00004100, 0x02000000, 0x00004008, 0x00000108,
280             0x02000100, 0x00004108, 0x00000000, 0x02000008,
281             0x00000008, 0x02000108, 0x02004108, 0x00004008,
282             0x02004000, 0x00000100, 0x00000108, 0x02004100,
283             0x02004100, 0x02000108, 0x00004008, 0x02004000,
284             0x00004000, 0x00000008, 0x02000008, 0x02000100,
285             0x02000000, 0x00004100, 0x02004108, 0x00000000,
286             0x00004108, 0x02000000, 0x00000100, 0x00004008,
287             0x02000108, 0x00000100, 0x00000000, 0x02004108,
288             0x02004008, 0x02004100, 0x00000108, 0x00004000,
289             0x00004100, 0x02004008, 0x02000100, 0x00000108,
290             0x00000008, 0x00004108, 0x02004000, 0x02000008,
291          },
292          {
293             /* nibble 5 */
294             0x20000010, 0x00080010, 0x00000000, 0x20080800,
295             0x00080010, 0x00000800, 0x20000810, 0x00080000,
296             0x00000810, 0x20080810, 0x00080800, 0x20000000,
297             0x20000800, 0x20000010, 0x20080000, 0x00080810,
298             0x00080000, 0x20000810, 0x20080010, 0x00000000,
299             0x00000800, 0x00000010, 0x20080800, 0x20080010,
300             0x20080810, 0x20080000, 0x20000000, 0x00000810,
301             0x00000010, 0x00080800, 0x00080810, 0x20000800,
302             0x00000810, 0x20000000, 0x20000800, 0x00080810,
303             0x20080800, 0x00080010, 0x00000000, 0x20000800,
304             0x20000000, 0x00000800, 0x20080010, 0x00080000,
305             0x00080010, 0x20080810, 0x00080800, 0x00000010,
306             0x20080810, 0x00080800, 0x00080000, 0x20000810,
307             0x20000010, 0x20080000, 0x00080810, 0x00000000,
308             0x00000800, 0x20000010, 0x20000810, 0x20080800,
309             0x20080000, 0x00000810, 0x00000010, 0x20080010,
310          },
311          {
312             /* nibble 6 */
313             0x00001000, 0x00000080, 0x00400080, 0x00400001,
314             0x00401081, 0x00001001, 0x00001080, 0x00000000,
315             0x00400000, 0x00400081, 0x00000081, 0x00401000,
316             0x00000001, 0x00401080, 0x00401000, 0x00000081,
317             0x00400081, 0x00001000, 0x00001001, 0x00401081,
318             0x00000000, 0x00400080, 0x00400001, 0x00001080,
319             0x00401001, 0x00001081, 0x00401080, 0x00000001,
320             0x00001081, 0x00401001, 0x00000080, 0x00400000,
321             0x00001081, 0x00401000, 0x00401001, 0x00000081,
322             0x00001000, 0x00000080, 0x00400000, 0x00401001,
323             0x00400081, 0x00001081, 0x00001080, 0x00000000,
324             0x00000080, 0x00400001, 0x00000001, 0x00400080,
325             0x00000000, 0x00400081, 0x00400080, 0x00001080,
326             0x00000081, 0x00001000, 0x00401081, 0x00400000,
327             0x00401080, 0x00000001, 0x00001001, 0x00401081,
328             0x00400001, 0x00401080, 0x00401000, 0x00001001,
329          },
330          {
331             /* nibble 7 */
332             0x08200020, 0x08208000, 0x00008020, 0x00000000,
333             0x08008000, 0x00200020, 0x08200000, 0x08208020,
334             0x00000020, 0x08000000, 0x00208000, 0x00008020,
335             0x00208020, 0x08008020, 0x08000020, 0x08200000,
336             0x00008000, 0x00208020, 0x00200020, 0x08008000,
337             0x08208020, 0x08000020, 0x00000000, 0x00208000,
338             0x08000000, 0x00200000, 0x08008020, 0x08200020,
339             0x00200000, 0x00008000, 0x08208000, 0x00000020,
340             0x00200000, 0x00008000, 0x08000020, 0x08208020,
341             0x00008020, 0x08000000, 0x00000000, 0x00208000,
342             0x08200020, 0x08008020, 0x08008000, 0x00200020,
343             0x08208000, 0x00000020, 0x00200020, 0x08008000,
344             0x08208020, 0x00200000, 0x08200000, 0x08000020,
345             0x00208000, 0x00008020, 0x08008020, 0x08200000,
346             0x00000020, 0x08208000, 0x00208020, 0x00000000,
347             0x08000000, 0x08200020, 0x00008000, 0x00208020
348          }
349       };
350    
351       private static final int cov_2char[] =
352       {
353          0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 
354          0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 
355          0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 
356          0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 
357          0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 
358          0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 
359          0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 
360          0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
361       };
362    
363       private static final int byteToUnsigned(byte b)
364       {
365          int value = (int)b;
366    
367          return(value >= 0 ? value : value + 256);
368       }
369    
370       private static int fourBytesToInt(byte b[], int offset)
371       {
372          int value;
373    
374          value  =  byteToUnsigned(b[offset++]);
375          value |= (byteToUnsigned(b[offset++]) <<  8);
376          value |= (byteToUnsigned(b[offset++]) << 16);
377          value |= (byteToUnsigned(b[offset++]) << 24);
378    
379          return(value);
380       }
381    
382       private static final void intToFourBytes(int iValue, byte b[], int
383    offset)
384       {
385          b[offset++] = (byte)((iValue)        & 0xff);
386          b[offset++] = (byte)((iValue >>> 8 ) & 0xff);
387          b[offset++] = (byte)((iValue >>> 16) & 0xff);
388          b[offset++] = (byte)((iValue >>> 24) & 0xff);
389       }
390    
391       private static final void PERM_OP(int a, int b, int n, int m, int
392    results[])
393       {
394          int t;
395    
396          t = ((a >>> n) ^ b) & m;
397          a ^= t << n;
398          b ^= t;
399    
400          results[0] = a;
401          results[1] = b;
402       }
403    
404       private static final int HPERM_OP(int a, int n, int m)
405       {
406          int t;
407    
408          t = ((a << (16 - n)) ^ a) & m;
409          a = a ^ t ^ (t >>> (16 - n));
410    
411          return(a);
412       }
413    
414       private static int [] des_set_key(byte key[])
415       {
416          int schedule[] = new int[ITERATIONS * 2];
417    
418          int c = fourBytesToInt(key, 0);
419          int d = fourBytesToInt(key, 4);
420    
421          int results[] = new int[2];
422    
423          PERM_OP(d, c, 4, 0x0f0f0f0f, results);
424          d = results[0]; c = results[1];
425    
426          c = HPERM_OP(c, -2, 0xcccc0000);
427          d = HPERM_OP(d, -2, 0xcccc0000);
428    
429          PERM_OP(d, c, 1, 0x55555555, results);
430          d = results[0]; c = results[1];
431    
432          PERM_OP(c, d, 8, 0x00ff00ff, results);
433          c = results[0]; d = results[1];
434    
435          PERM_OP(d, c, 1, 0x55555555, results);
436          d = results[0]; c = results[1];
437    
438          d = (((d & 0x000000ff) <<  16) |  (d & 0x0000ff00)     |
439               ((d & 0x00ff0000) >>> 16) | ((c & 0xf0000000) >>> 4));
440          c &= 0x0fffffff;
441    
442          int s, t;
443          int j = 0;
444    
445          for(int i = 0; i < ITERATIONS; i ++)
446          {
447             if(shifts2[i])
448             {
449                c = (c >>> 2) | (c << 26);
450                d = (d >>> 2) | (d << 26);
451             }
452             else
453             {
454                c = (c >>> 1) | (c << 27);
455                d = (d >>> 1) | (d << 27);
456             }
457    
458             c &= 0x0fffffff;
459             d &= 0x0fffffff;
460    
461             s = skb[0][ (c       ) & 0x3f                       ]|
462                 skb[1][((c >>>  6) & 0x03) | ((c >>>  7) & 0x3c)]|
463                 skb[2][((c >>> 13) & 0x0f) | ((c >>> 14) & 0x30)]|
464                 skb[3][((c >>> 20) & 0x01) | ((c >>> 21) & 0x06) |
465                                              ((c >>> 22) & 0x38)];
466    
467             t = skb[4][ (d     )  & 0x3f                       ]|
468                 skb[5][((d >>> 7) & 0x03) | ((d >>>  8) & 0x3c)]|
469                 skb[6][ (d >>>15) & 0x3f                       ]|
470                 skb[7][((d >>>21) & 0x0f) | ((d >>> 22) & 0x30)];
471    
472             schedule[j++] = ((t <<  16) | (s & 0x0000ffff)) & 0xffffffff;
473             s             = ((s >>> 16) | (t & 0xffff0000));
474    
475             s             = (s << 4) | (s >>> 28);
476             schedule[j++] = s & 0xffffffff;
477          }
478          return(schedule);
479       }
480    
481       private static final int D_ENCRYPT
482       (
483          int L, int R, int S, int E0, int E1, int s[]
484       )
485       {
486          int t, u, v;
487    
488          v = R ^ (R >>> 16);
489          u = v & E0;
490          v = v & E1;
491          u = (u ^ (u << 16)) ^ R ^ s[S];
492          t = (v ^ (v << 16)) ^ R ^ s[S + 1];
493          t = (t >>> 4) | (t << 28);
494    
495          L ^= SPtrans[1][(t       ) & 0x3f] |
496               SPtrans[3][(t >>>  8) & 0x3f] |
497               SPtrans[5][(t >>> 16) & 0x3f] |
498               SPtrans[7][(t >>> 24) & 0x3f] |
499               SPtrans[0][(u       ) & 0x3f] |
500               SPtrans[2][(u >>>  8) & 0x3f] |
501               SPtrans[4][(u >>> 16) & 0x3f] |
502               SPtrans[6][(u >>> 24) & 0x3f];
503    
504          return(L);
505       }
506    
507       private static final int [] body(int schedule[], int Eswap0, int Eswap1)
508       {
509          int left = 0;
510          int right = 0;
511          int t     = 0;
512    
513          for(int j = 0; j < 25; j ++)
514          {
515             for(int i = 0; i < ITERATIONS * 2; i += 4)
516             {
517                left  = D_ENCRYPT(left,  right, i,     Eswap0, Eswap1,
518    schedule);
519                right = D_ENCRYPT(right, left,  i + 2, Eswap0, Eswap1,
520    schedule);
521             }
522             t     = left; 
523             left  = right; 
524             right = t;
525          }
526    
527          t = right;
528    
529          right = (left >>> 1) | (left << 31);
530          left  = (t    >>> 1) | (t    << 31);
531    
532          left  &= 0xffffffff;
533          right &= 0xffffffff;
534    
535          int results[] = new int[2];
536    
537          PERM_OP(right, left, 1, 0x55555555, results); 
538          right = results[0]; left = results[1];
539    
540          PERM_OP(left, right, 8, 0x00ff00ff, results); 
541          left = results[0]; right = results[1];
542    
543          PERM_OP(right, left, 2, 0x33333333, results); 
544          right = results[0]; left = results[1];
545    
546          PERM_OP(left, right, 16, 0x0000ffff, results);
547          left = results[0]; right = results[1];
548    
549          PERM_OP(right, left, 4, 0x0f0f0f0f, results);
550          right = results[0]; left = results[1];
551    
552          int out[] = new int[2];
553    
554          out[0] = left; out[1] = right;
555    
556          return(out);
557       }
558    
559       public static final String crypt(String salt, String original)
560       {
561          while(salt.length() < 2)
562             salt += "A";
563    
564          StringBuilder buffer = new StringBuilder("             ");
565    
566          char charZero = salt.charAt(0);
567          char charOne  = salt.charAt(1);
568    
569          buffer.setCharAt(0, charZero);
570          buffer.setCharAt(1, charOne);
571    
572          int Eswap0 = con_salt[(int)charZero];
573          int Eswap1 = con_salt[(int)charOne] << 4;
574     
575          byte key[] = new byte[8];
576    
577          for(int i = 0; i < key.length; i ++)
578             key[i] = (byte)0;
579    
580          for(int i = 0; i < key.length && i < original.length(); i ++)
581          {
582             int iChar = (int)original.charAt(i);
583    
584             key[i] = (byte)(iChar << 1);
585          }
586    
587          int schedule[] = des_set_key(key);
588          int out[]      = body(schedule, Eswap0, Eswap1);
589    
590          byte b[] = new byte[9];
591    
592          intToFourBytes(out[0], b, 0);
593          intToFourBytes(out[1], b, 4);
594          b[8] = 0;
595    
596          for(int i = 2, y = 0, u = 0x80; i < 13; i ++)
597          {
598             for(int j = 0, c = 0; j < 6; j ++)
599             {
600                c <<= 1;
601    
602                if(((int)b[y] & u) != 0)
603                   c |= 1;
604    
605                u >>>= 1;
606    
607                if(u == 0)
608                {
609                   y++;
610                   u = 0x80;
611                }
612                buffer.setCharAt(i, (char)cov_2char[c]);
613             }
614          }
615          return(buffer.toString());
616       }
617    
618       public static void main(String args[])
619       {
620          if(args.length >= 2)
621          {
622             System.out.println
623             (
624                "[" + args[0] + "] [" + args[1] + "] => [" +
625                JCrypt.crypt(args[0], args[1]) + "]"
626             );
627          }
628          else
629          {
630            System.out.println( "Usage: JCrypt <salt> <password>" );
631            System.exit( 1 );
632          }
633       }
634    }