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