我想把这个a71e2023-9aaa-4d4e-a83d-4c71f6c41911字符串转为16个字符或更少的字符串,要是唯一的,请问怎么实现?

解决方案 »

  1.   

    答:很简单啊。每四位一组,构成一个UNICODE字符。
    String ss=""+(char)Integer.parseInt("a71e",16)+(char)Integer.parseInt("2023",16)+
                (char)Integer.parseInt("9aaa",16)+....
    由于-位置固定,因此可以不考虑。
    这样只要8个字符的字符串就行了。
    而且还可以正确还原出来。
      

  2.   

    好象不行哦
    String ss2=""+(char)Integer.parseInt("2023",16);
    System.out.println("String="+ss2);
    输出结果:
    String=?
      

  3.   

    1.先生成你开始的32位不重复的字符串。    UUID uuid = UUID.randomUUID();
        return uuid.toString();
    2.从右边截取16位。我这里用到Apache的Commons-lang包。下载这个包,或者你手写截取也可。    StringUtils.right(MiscToolBox.getSimpleId(), 16);
    3.通过上面生成的16位ID,其实重复的几率已经很低了。但是为防止万一,需要先从数据库中查一下。没有插入,
    否则再生成一遍这个ID。                String id = "";
    while(true) {
    id = 上面生成ID的方面;
                            if (通过Id查找数据库中这个ID的数量>0) //再生成一遍
    continue;
    else break;
    }
    return id ;                   
      

  4.   

    楼上的,我的32位UUID不是我自己生成的,是别人传过来的,我不可能再重新生成一遍,截取后16位我自己也想过,但是确实有可能出现重复的
      

  5.   

    16个?
    MD5Hash下说 /**
     * MD5加密算法,进行了简单的封装,以适用于加,解密字符串的校验。
     * 
     * @param buf 需要MD5加密字节数组。
     * @param offset 加密数据起始位置。
     * @param length 需要加密的数组长度。
     * @return
     */
    public static byte[] MD5Hash(byte[] buf, int offset, int length)
    throws Exception {
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(buf, offset, length);
    return md.digest();
    } /**
     * 字节数组转换为二行制表示
     * 
     * @param inStr  需要转换字节数组。
     * @return 字节数组的二进制表示
     */
    public static String byte2hex(byte[] inStr) {
    String stmp;
    StringBuffer out = new StringBuffer(inStr.length * 2); for (int n = 0; n < inStr.length; n++) {
    // 字节做“与”运算,去除高位置字节 11111111
    stmp = Integer.toHexString(inStr[n] & 0xFF);
    if (stmp.length() == 1) {
    // 如果是0至F的单位字符串,则添加0
    out.append("0" + stmp);
    } else {
    out.append(stmp);
    }
    }
    return out.toString();
    }
      

  6.   

    String c = "a71e2023-9aaa-4d4e-a83d-4c71f6c41911";
    try {
    String h = Md5.byte2hex(Md5.MD5Hash(c.getBytes(), 0, c.length()));
    System.out.println(h);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }得到的结果:eabf857ef96f7a2f93545c718e4e449a
    是32位的啊
      

  7.   

    楼主数据库字段是 char(16) 类型的?
      

  8.   

    给楼主个思路:"a71e2023-9aaa-4d4e-a83d-4c71f6c41911" 如果把其中-去掉,可以把剩下的字符看作一个32位的16进制整数,按每位16进制对应于4位二进制信息,UUID可以看作一个 32 * 4 = 128 bit 的数据块(本质上也如此),而数据库中 char(16) 字段的编码如果是Unicode的而每个Unicode字符需要16位即2个字节表示,那么16个字节共 16 * 16 = 256 bit,实际上不是数据量的压缩而是扩充,所以如果能修改数据库结构,可以直接存储这个128位的数据块,带来的好处是即节省数据库空间,又可以在二进制基础上直接作比较运算,效率要比字符串比较高(省去了编码解码的运算和时间)。
      

  9.   

    /*
     * FileName: Test.java
     * Author:   SageZk
     * Date:     2008-06-03
     */public class Test { public static void main(String[] args) {
    String uuid = "a71e2023-9aaa-4d4e-a83d-4c71f6c41911";
    String st = uuid.replaceAll("\\-", "");
    StringBuffer sb = new StringBuffer(16);
    for (int i = 0; i < 32; i = i + 2) {
    sb.append((char) (Integer.parseInt(st.substring(i, i + 2), 16) + '我'));
    }
    String sr = sb.toString();
    System.out.println(uuid);
    System.out.println(sr); }}
    可以把 '我' 换成其他字符。
      

  10.   

    楼上的输出结果:"抸戯戱戴披抻扞扟抹扎扝抂指拕截戢"
    数据库里char(16)能存下16个中文字符吗?
      

  11.   


    String uuid = "a71e2023-9aaa-4d4e-a83d-4c71f6c41911";
            String st = uuid.replaceAll("\\-", "");
            StringBuffer sb = new StringBuffer(16);
            for (int i = 0; i < 32; i = i + 2) {
                sb.append((char) (Integer.parseInt(st.substring(i, i + 2), 16) + 'a'));
            }
            String sr = sb.toString();
            System.out.println(uuid);
            System.out.println(sr);
            System.out.println("?????????????zr".equals(sr));输出结果:
    a71e2023-9aaa-4d4e-a83d-4c71f6c41911
    ?????????????zr
    false
    这样我从数据库取出来不是不能匹配了吗
      

  12.   

    那要看 char(16) 字段编码类型,如果是 Unicode 或 GBK 的都没问题。
      

  13.   

    测试成功,感谢sagezk的帮助,结分
      

  14.   

    可以用256进制来表示你那个字符串,就从32位缩到16位了
    (11111111(2)=FF(16)=ÿ(256))不过有个缺点,字符串传递的时候不能复制+粘贴,那样的话有些字符就失效了,AscII中有很多不可打印字符
    不过数据始终用二进制传递就可以了,,应该不困难
    public class Java2 {
    public static String getConvString(String str) {
    String tmp=str.replace("-","");
    String strOut="";
    for (int i=0; i<tmp.length()-1; i+=2) {
    try {
    strOut+=(char)Integer.parseInt(tmp.substring(i,i+2),16);
    } catch (Exception e) {return null;}
    }
    return strOut;
    }
    public static String getSourceString(String str) {
    String strOut="";
    for (int i=0; i<str.length(); i++) {
    if (i==4 || i==6 || i==8 || i==10) {
    strOut+="-";
    }
    int n=(int)(str.charAt(i));
    strOut+=Integer.toHexString(n);
    }
    return strOut;
    }

    public static void main(String[] args) {
    String s="a71e2023-9aaa-4d4e-a83d-4c71f6c41911";
    String string=getConvString(s);
    System.out.println("原来 的字符串: "+s);
    System.out.println("转换过的字符串: "+string);
    System.out.println("还原过的字符串: "+getSourceString(string));
    }
    }
    得到的结果:原来 的字符串: a71e2023-9aaa-4d4e-a83d-4c71f6c41911
    转换过的字符串: § #??MN¨=Lq??
    还原过的字符串: a71e2023-9aaa-4d4e-a83d-4c71f6c41911