crypt.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 592 行 · 第 1/2 页

JAVA
592
字号
/* * This implementation of the unix crypt function is based on * Eric Young's DES implementation from OpenSSL. */package com.caucho.quercus.lib.string;/** * Crypt. */public class Crypt {  public static String crypt(String keyString, String salt)  {    int len = keyString.length();    if (8 < len)      len = 8;    int swap0 = toSalt(salt.charAt(0)) << 2;    int swap1 = toSalt(salt.charAt(1)) << 6;    char result[] = new char[12];    byte key[] = new byte[8];    int i;    for (i = 0; i < len; i++) {      char ch = keyString.charAt(i);      key[i] = (byte) (ch << 1);    }    for (; i < 8; i++) {      key[i] = 0;    }    int []keySchedule = new int[32];    setKeySchedule(key, keySchedule);    long value = encrypt(keySchedule, swap0, swap1);    return resultToString(salt, value);  }  private static int toSalt(char ch)  {    if (ch < 0x3a)      return ch - 0x2e;    else if (ch < 0x5b)      return ch - 0x3a + 0x05;    else      return ch - 0x5b + 0x20;  }  private static void setKeySchedule(byte []key, int []schedule)  {    int c = ((key[0] & 0xff) |	     ((key[1] & 0xff) << 8) |	     ((key[2] & 0xff) << 16) |	     ((key[3] & 0xff) << 24));    int d = ((key[4] & 0xff) |	     ((key[5] & 0xff) << 8) |	     ((key[6] & 0xff) << 16) |	     ((key[7] & 0xff) << 24));    // PERM_OP (d,c,t,4,0x0f0f0f0fL);    int temp = ((d >>> 4) ^ c) & 0x0f0f0f0f;    c ^= temp;    d ^= temp << 4;    // HPERM_OP(c,t,-2,0xcccc0000L);    temp = ((c << 18) ^ c) & 0xcccc0000;    c ^= temp ^ (temp >>> 18);    // HPERM_OP(d,t,-2,0xcccc0000L);    temp = ((d << 18) ^ d) & 0xcccc0000;    d ^= temp ^ (temp >>> 18);    // PERM_OP (d,c,t,1,0x55555555L);    temp = ((d >>> 1) ^ c) & 0x55555555;    c ^= temp;    d ^= temp << 1;    // PERM_OP (c,d,t,8,0x00ff00ffL);    temp = ((c >>> 8) ^ d) & 0x00ff00ff;    d ^= temp;    c ^= temp << 8;    // PERM_OP (d,c,t,1,0x55555555L);    temp = ((d >>> 1) ^ c) & 0x55555555;    c ^= temp;    d ^= temp << 1;    d =	(((d & 0x000000ff) << 16) |	 (d & 0x0000ff00) |	 ((d & 0x00ff0000) >>> 16) |	 ((c & 0xf0000000) >>> 4));    c &= 0x0fffffffL;    int k = 0;    for (int i = 0; i < 16; i++) {      if (KEY_SHIFTS[i]) {	c = (c >> 2) | (c << 26);	d = (d >> 2) | (d << 26);      }      else {	c = (c >> 1) | (c << 27);	d = (d >> 1) | (d << 27);      }      c &= 0x0fffffff;      d &= 0x0fffffff;      int s = (skb_0[ (c      ) & 0x3f] |	       skb_1[((c >> 6) & 0x03) |		     ((c >> 7) & 0x3c)] |	       skb_2[((c >> 13) & 0x0f) |		     ((c >> 14) & 0x30)] |	       skb_3[((c >> 20) & 0x01) |		     ((c >> 21) & 0x06) |		     ((c >> 22) & 0x38)]);      int t = (skb_4[ (d    ) & 0x3f] |	       skb_5[((d >> 7) & 0x03) |		     ((d >> 8) & 0x3c)] |	       skb_6[ (d >> 15) & 0x3f] |	       skb_7[((d >> 21) & 0x0f) |		     ((d >> 22) & 0x30)]);      int t2 = (t << 16) | (s & 0x0000ffff);      schedule[k++] = rotate(t2, 30);      t2 = (s >>> 16) | (t & 0xffff0000);      schedule[k++] = rotate(t2, 26);    }  }  private static long encrypt(int []key, int swap0, int swap1)  {    int l = 0;    int r = 0;    int temp;    for (int j = 0; j < 25; j++) {      for (int i = 0; i < 32; i += 8) {	l = encrypt(l, r, key[i + 0], key[i + 1], swap0, swap1);	r = encrypt(r, l, key[i + 2], key[i + 3], swap0, swap1);	l = encrypt(l, r, key[i + 4], key[i + 5], swap0, swap1);	r = encrypt(r, l, key[i + 6], key[i + 7], swap0, swap1);      }      temp = l;      l = r;      r = temp;    }    // l=ROTATE(l,3)&0xffffffffL;    l = rotate(l, 3);    // r=ROTATE(r,3)&0xffffffffL;    r = rotate(r, 3);    // PERM_OP(l,r,t, 1,0x55555555L);    temp = ((l >>> 1) ^ r) & 0x55555555;    r ^= temp;    l ^= temp << 1;    // PERM_OP(r,l,t, 8,0x00ff00ffL);    temp = ((r >>> 8) ^ l) & 0x00ff00ff;    l ^= temp;    r ^= temp << 8;    // PERM_OP(l,r,t, 2,0x33333333L);    temp = ((l >>> 2) ^ r) & 0x33333333;    r ^= temp;    l ^= temp << 2;    // PERM_OP(r,l,t,16,0x0000ffffL);    temp = ((r >>> 16) ^ l) & 0x0000ffff;    l ^= temp;    r ^= temp << 16;    // PERM_OP(l,r,t, 4,0x0f0f0f0fL);    temp = ((l >>> 4) ^ r) & 0x0f0f0f0f;    r ^= temp;    l ^= temp << 4;    return ((long) l << 32L) + ((long) r & 0xffffffffL);  }  private static int encrypt(int l, int r,			     int key0, int key1,			     int swap0, int swap1)  {    int t = r ^ (r >>> 16);    int x = t & swap0;    int y = t & swap1;    x ^= r ^ key0 ^ (x << 16);    y ^= r ^ key1 ^ (y << 16);    y = rotate(y, 4);    l ^= (des_0[(x >>  2) & 0x3f] ^	  des_2[(x >> 10) & 0x3f] ^	  des_4[(x >> 18) & 0x3f] ^	  des_6[(x >> 26) & 0x3f] ^	  des_1[(y >>  2) & 0x3f] ^	  des_3[(y >> 10) & 0x3f] ^	  des_5[(y >> 18) & 0x3f] ^	  des_7[(y >> 26) & 0x3f]);    return l;  }  private static int rotate(int v, int n)  {    return (v >>> n) + (v << (32 - n));  }  private static String resultToString(String salt, long v)  {    StringBuilder sb = new StringBuilder();    if (salt.length() > 2)      sb.append(salt.substring(0, 2));    else      sb.append(salt);    v = (((v & 0x00000000000000ffL) << 56) |	 ((v & 0x000000000000ff00L) << 40) |	 ((v & 0x0000000000ff0000L) << 24) |	 ((v & 0x00000000ff000000L) << 8) |	 ((v & 0x000000ff00000000L) >>> 8) |	 ((v & 0x0000ff0000000000L) >>> 24) |	 ((v & 0x00ff000000000000L) >>> 40) |	 ((v & 0xff00000000000000L) >>> 56));    sb.append(resultToChar(v >> 58));    sb.append(resultToChar(v >> 52));    sb.append(resultToChar(v >> 46));    sb.append(resultToChar(v >> 40));    sb.append(resultToChar(v >> 34));    sb.append(resultToChar(v >> 28));    sb.append(resultToChar(v >> 22));    sb.append(resultToChar(v >> 16));    sb.append(resultToChar(v >> 10));    sb.append(resultToChar(v >> 4));    sb.append(resultToChar(v << 2));    return sb.toString();  }  static char resultToChar(long result)  {    int v = (int) (result & 0x3f);    if (v < 0x0c)      return (char) (v + 0x2e);    else if (v < 0x26)      return (char) (v + 0x41 - 0x0c);    else      return (char) (v + 0x61 - 0x26);  }  private final static boolean []KEY_SHIFTS = new boolean[] {    false, false, true, true, true, true, true, true,    false, true,  true, true, true, true, true, false  };  private final static int []REVERSE_BITS = new int[] {    0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38,    0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c,    0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a,    0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e,    0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39,    0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d,    0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b,    0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f,  };  private static final int []des_0 = new int[] {    0x02080800, 0x00080000, 0x02000002, 0x02080802,    0x02000000, 0x00080802, 0x00080002, 0x02000002,    0x00080802, 0x02080800, 0x02080000, 0x00000802,    0x02000802, 0x02000000, 0x00000000, 0x00080002,    0x00080000, 0x00000002, 0x02000800, 0x00080800,    0x02080802, 0x02080000, 0x00000802, 0x02000800,    0x00000002, 0x00000800, 0x00080800, 0x02080002,    0x00000800, 0x02000802, 0x02080002, 0x00000000,    0x00000000, 0x02080802, 0x02000800, 0x00080002,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?