在项目中有时我们采用uuid来作为唯一标识, 但是去掉-后还是有32位,有时就会很长, 这时我们可以将其进行转换,进行缩短。

思路

我们调用Java的接口获取的UUID, 是一串16进制的字符串,字符串的每个字符都位于0-9和a-f中, 如:0c05d6b4a091435190b33e75698c051d。

我们可以将两两做位运算, 运算后的结果, 从预设的字符库中进行取值,一般设置的字符库都是数字加上大小写字母,这样总计有62个可使用。

那我们需要将两两进行位运算的结果在字符库中, 比如: 16进制f的二进制是0000 1111, 我们可以将其右移两位0011 1100, 然后与另一位右移两位进行或位运算|, 或位运算 两个位都为0时,结果才为0。位运算后最大的结果为0011 1111 ,十进制为63, 也就是说字符库需要准备64个字符, 上面已经有62个了, 这时在加两个特殊字符-_。

这样两两进行位运算后, 保证值0-63共64个值都能在字符库中找到对应的值, 从而实现转换, 将UUID从32长度转换为16长度, 下面就上代码

package com.moringstar.tools;

public class UUIDConvert {
    private final static char[] CHAR_MAP = {'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', '-', '_'};

    /**
     * 32位UUID 转换为 16位
     *
     * @param uuid 32位UUID
     * @return 16位UUID
     */
    public static String convert32To16(String uuid) {
        StringBuilder stringBuffer = new StringBuilder();
        int index;
        int[] buff = new int[2];
        int length = uuid.length();
        for (int i = 0; i < length; i++) {
            index = i % 2;
            buff[index] = Integer.parseInt("" + uuid.charAt(i), 16);
            if (index == 1) {
                stringBuffer.append(CHAR_MAP[buff[0] << 2 | buff[1] >>> 2]);
            }
        }
        return stringBuffer.toString();
    }

}

运行结果如下:


和光同尘,与时舒卷;戢鳞潜翼,思属风云