UUID还是比较常用的,尤其在web应用里。
有时在URL中传播,感觉比较长,于是想对其进行缩短,查询了一些资料,发现目前最短是到 22 位(使用URL传播非转义字符,结合Base64)
废话少说,代码奉上:
public class UuidBase64ShortMap implements StringShortMap{
/**
*
*把UUID 转为 22位长字符串
*/
public String shorter(String s) {
char[] res = Base64.encode(asBytes(s));
return new String(res,0,res.length-2);
}
/**
*
*把22位长字符串转为 UUID
*/
public String recover(String s) {
int len = s.length();
char[] chars = new char[len+2];
chars[len]=chars[len+1]='_';
for(int i=0;i<len;i++){
chars[i]=s.charAt(i);
}
return toUUID(Base64.decode(chars)).toString();
}
public static byte[] asBytes(String id) {
UUID uuid=UUID.fromString(id);
long msb = uuid.getMostSignificantBits();
long lsb = uuid.getLeastSignificantBits();
byte[] buffer = new byte[16];
for (int i = 0; i < 8; i++) {
buffer[i] = (byte) (msb >>> 8 * (7 - i));
}
for (int i = 8; i < 16; i++) {
buffer[i] = (byte) (lsb >>> 8 * (7 - i));
}
return buffer;
}
public static UUID toUUID(byte[] byteArray) {
long msb = 0;
long lsb = 0;
for (int i = 0; i < 8; i++)
msb = (msb << 8) | (byteArray[i] & 0xff);
for (int i = 8; i < 16; i++)
lsb = (lsb << 8) | (byteArray[i] & 0xff);
UUID result = new UUID(msb, lsb);
return result;
}
public static void main(String[] args) {
StringShortMap shortm = new UuidBase64ShortMap();
// String uuid = "3b01174f-3139-4a5b-a949-bb7e80b55f91";
// System.out.println(Base64.encode(uuid));
// String shorter= shortm.shorter(uuid);
// System.out.println(shorter);
// System.out.println(shortm.recover(shorter) +"\t" + uuid);
// for(int i=0;i<100000;i++){
// String Uuid = UUID.randomUUID().toString();
// System.out.println(Uuid +"\t" + shortm.shorter(Uuid));
// }
String[] uuids={"f6e0e040-be3d-4573-964c-88724a8fa7d3","c19b9de1-f33a-494b-afbe-f06817218d63","f08f0b2c-66fb-41a3-99c3-ac206089c3ad"};
for(String s :uuids){
System.out.println(shortm.shorter(s));
}
}
}
运行结果
9uDgQL49RXOWTIhySo*n0w
wZud4fM6SUuvvvBoFyGNYw
8I8LLGb7QaOZw6wgYInDrQ
有更好的方案,欢迎讨论!!