QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: Alex_Sune

Java下如何将byte[]按自定义编码转换成String?

[复制链接]
 楼主| 发表于 2004-10-29 20:43:08 | 显示全部楼层
刚发现,byte做了运算就成了int了。
回复

使用道具 举报

 楼主| 发表于 2004-10-29 20:50:47 | 显示全部楼层
我现在基本有个方向了,就是在原来的byte[16]里每次取六个bits,在最前面加两个bits的零,然后赋给另一个byte,得到一个byte[21],剩下的就容易了。
回复

使用道具 举报

发表于 2004-10-30 10:53:49 | 显示全部楼层
没太看懂你的意思,不过用以下的方法,把Byte转换成字符串,处理以后转回成Byte,
会不会让事情简单一点。
[code:1]
                // exsample value
                byte byteValue = 126;
                // byte ==> binary string
                String sBitStr = Integer.toBinaryString(byteValue);
                // binary string ==> byte
                Byte newByte = Byte.valueOf(sBitStr,2);
               
                // output
                System.out.println("@@@:" + sBitStr);
                System.out.println("@@@:" + newByte);
[/code:1]
输出:
[code:1]
  @@@:1111110
  @@@:126
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-10-30 13:30:30 | 显示全部楼层
自己用蛮干的方式做出来了,很粗糙,感觉乱七八糟的,大家看看能不能帮忙改进一下。[code:1]import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Password {
  //构造转换表
  private static final char[] CodeTBL = {
    '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
    'w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L',
    'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','#','*',  
  };
  //这就是整个程序的关键所在
  private static String digestToPswd(byte[] digest) {
    //因为下面的循环每次处理三个byte,并获得四个char,所以Password的尺寸只能是这样
    char[] Password = new char[(((digest.length) / 3) * 4)];
    //这个for循环的作用就是把原来的byte[]按每次六位的方式重新组合,然后从转换表中取出对应的符号,赋给Password
    for (int i = 0, j = 0;
      i + 3 < Password.length && j + 2 < digest.length;
      j++) {
      //取本次循环第一个byte的前六位,因为Java没有unsigned,所以需要用 ?: 运算来保证转换过程中二进制序列没有被改变
      Password[i++] =
        CodeTBL[(
          ((digest[j] < 0) ? (256 + digest[j]) : (int) (digest[j]))
            >> 2)];
      //取本次循环第一个byte的后两位,前移,让出空间,然后加上本次循环第二个byte的前四位
      Password[i++] =
        CodeTBL[(
          ((((digest[j] < 0) ? (256 + digest[j]) : (int) (digest[j]))
            & 3)
            << 4)
            + (((digest[++j] < 0)
              ? (256 + digest[j])
              : (int) (digest[j]))
              >> 4))];
      //取本次循环第二个byte的后四位,前移,让出空间,然后加上本次循环第三个byte的前两位
      Password[i++] =
        CodeTBL[(
          ((((digest[j] < 0) ? (256 + digest[j]) : (int) (digest[j]))
            & 15)
            << 2)
            + (((digest[++j] < 0)
              ? (256 + digest[j])
              : (int) (digest[j]))
              >> 6))];
      //取本次循环第三个byte的后六位
      Password[i++] =
        CodeTBL[(
          ((digest[j] < 0) ? (256 + digest[j]) : (int) (digest[j]))
            & 63)];
    }
    return new String(Password);
  }

  private static MessageDigest MD;

  static{
    try {
      MD = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }
  }

  private MD5Password() {
  }

  public static String getPassword(byte[] input) {
    MD.update(input);
    return digestToPswd(MD.digest());
  }

  public static void main(String[] args) {
    byte[] bt={1,6,55,25,34,25,78,99};
    System.out.println(getPassword(bt));
  }
}
[/code:1]这里还有一段利用Random类来构造转换表的代码,也麻烦大家帮忙改进一下。
[code:1]import java.util.Random;

public class BuildCodeTBL {
  
  private final char[] CodeTBL = {
    '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
    'w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L',
    'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','#','*',  
  };
  private char[] newCodeTBL = new char[CodeTBL.length];
  private int[] TBL = new int[newCodeTBL.length];
  private Random rdm = new Random();
  private boolean bl;

  public BuildCodeTBL() {
    super();
    for (int i = 0, j = 0; i < TBL.length; ) {
      j = rdm.nextInt(65);
      bl = false;
      for (int k = 0; k <= i; k++) {
        bl |= (j == TBL[k]);
      }
      if (!bl) {
        TBL[i] = j - 1;
        i++;
      }
    }
    for (int i = 0; i < TBL.length && i < newCodeTBL.length; i++) {
      newCodeTBL[i] = CodeTBL[TBL[i]];
    }
  }

  public static void main(String[] args) {
    BuildCodeTBL bct = new BuildCodeTBL();
    for (int i=0;i<4;i++){
      for (int j=0;j<16;j++){
        System.out.print("'");
        System.out.print(bct.newCodeTBL[i*16+j]);
        System.out.print("',");
      }
      System.out.println();
    }
  }
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-10-31 15:16:32 | 显示全部楼层
差不多了,这样应该就可以了,剩下的就是扩展能接受的类型了。[code:1]
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class HashPasswords {

  public String getPassword(byte[] input) {
    byte[] digest;
    synchronized (MD) {
      digest = MD.digest(input);
      MD.reset();
    }
    return digestToPswd(digest);
  }

  public String getPassword(String input) {
    return getPassword(input.getBytes());
  }

  public String getPassword(String[] input) {
    StringBuffer StrBuffer = new StringBuffer();
    for (int i = 0; i < input.length; i++) {
      StrBuffer.append(input[i]);
    }
    return getPassword(StrBuffer.substring(0).getBytes());
  }

  private MessageDigest MD;
  public HashPasswords(String HashAlgorithm) {
    super();
    try {
      MD = MessageDigest.getInstance(HashAlgorithm);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }
  }

  private static final char[] CodeTBL = {
    '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
    'w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L',
    'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','#','*'};
  private static String digestToPswd(byte[] bytes) {

    int lb = bytes.length;
    char[] Password = new char[((lb / 3 * 4) + (lb % 3))];
    int lP = Password.length;

    for (int i = 0, j = 0; i + 3 < lP && j + 2 < lb; j++) {
      Password[i++] = CodeTBL[(((bytes[j] < 0) ? (256 + bytes[j]) : (int) (bytes[j])) >> 2)];
      Password[i++] = CodeTBL[(((((bytes[j] < 0) ? (256 + bytes[j]) : (int) (bytes[j])) & 3) << 4) +
              (((bytes[++j] < 0) ? (256 + bytes[j]) : (int) (bytes[j])) >> 4))];
      Password[i++] = CodeTBL[(((((bytes[j] < 0) ? (256 + bytes[j]) : (int) (bytes[j])) & 15) << 2) +
              (((bytes[++j] < 0) ? (256 + bytes[j]) : (int) (bytes[j])) >> 6))];
      Password[i++] = CodeTBL[(((bytes[j] < 0) ? (256 + bytes[j]) : (int) (bytes[j])) & 63)];
    }
    switch (lb % 3) {
      case 0 :
        {
          break;
        }
      case 1 :
        {
          lP-=1;lb-=1;
          Password[lP] = CodeTBL[(((bytes[lb] < 0) ? (256 + bytes[lb]) : (int) (bytes[lb])) >> 2)];
          break;
        }
      case 2 :
        {
          lP-=2;lb-=2;
          Password[lP] = CodeTBL[(((bytes[lb] < 0) ? (256 + bytes[lb]) : (int) (bytes[lb])) >> 2)];lP++;
          Password[lP] = CodeTBL[(((((bytes[lb] < 0) ? (256 + bytes[lb]) : (int) (bytes[lb])) & 3) << 4) +
                   (((bytes[++lb] < 0) ? (256 + bytes[lb]) : (int) (bytes[lb])) >> 4))];
          break;
        }
    }
    return new String(Password);
  }
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-10-31 15:17:04 | 显示全部楼层
另外我还有一个问题,这个MD = MessageDigest.getInstance(HashAlgorithm);的异常处理是用try/catch包围好还是直接添加抛出声明好呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-7 05:25 , Processed in 0.045334 second(s), 13 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表