用于编码UUIDS的传统算法的替代方案(例如Base32,Base62)

时间:2011-07-07 06:41:34

标签: algorithm guid uuid

我们需要将大量的UUIDS转换为xml兼容的字符串。如果我们使用Base32算法(将每个5位映射到32个字符中的一个),这将导致26个字符串,如果我们使用Base62算法(迭代地将128位整数除以62并将模数记录为62个字符之一)这导致22个字符串。虽然base62返回更短的字符串,但它更加cpu密集,因此我们坚持使用Base32(由于xml,Base64不是一个选项)。

您是否知道可以帮助我们的任何其他类型的编码算法?是否存在类似Base32的位模式编码算法的变体,可以与不是2的幂的基数一起使用?或者是否有混合算法将第一种方法与第二种算法的方法结合起来?如果可能的话,我们希望将char字符串减少到少于26。

2 个答案:

答案 0 :(得分:3)

你提到62,这表明你将字母表限制为A-Z(大写和小写)和数字0-9。为什么不在该列表中添加另外两个与XML兼容的字符,例如+.~!以使该数字达到64?您将能够进行位移而不是除法,这应该使算法与Base32一样快,并减少字符串大小。

编辑:由于这些字符也可用于其他尚未指定的语言的限制,您可能会想要转义一些字符来代表您的64个选项。例如,如果使用_作为转义字符,则可以使用_1和_2表示选项63和64.原始问题中提到的统计数据表明UUIDS是128位,因此如果存在,我们的Base64会给出22个字符没有转义,并且最多可以转发4件物品,保持在26个字符内。

答案 1 :(得分:0)

Wikipedia提供两种版本的Base64,可在XML命名空间中使用。

http://en.wikipedia.org/wiki/Base64#XML。我编写了下面的JAVA,用于在Java中执行URLSafe,UUID,(调用ObjectReturned.toString()将其作为guid字符串)。

我见过其他Java代码应该非常快,可以很容易地修改为XML安全变体:

http://iharder.sourceforge.net/current/java/base64/

代码如下。保存在名为UUIDUtil.java的文件中

public class UUIDUtil{
public static UUID combUUID(){
    private UUID srcUUID = UUID.randomUUID();;
    private java.sql.Timestamp ts = new java.sql.Timestamp(Calendar.getInstance().getTime().getTime());

    long upper16OfLowerUUID = this.zeroLower48BitsOfLong( srcUUID.getLeastSignificantBits() );
    long lower48Time = UUIDUtil.zeroUpper16BitsOfLong( ts );
    long lowerLongForNewUUID = upper16OfLowerUUID | lower48Time;
    return new UUID( srcUUID.getMostSignificantBits(), lowerLongForNewUUID );
}   
public static base64URLSafeOfUUIDObject( UUID uuid ){
    byte[] bytes = ByteBuffer.allocate(16).putLong(0, uuid.getLeastSignificantBits()).putLong(8, uuid.getMostSignificantBits()).array();
    return Base64.encodeBase64URLSafeString( bytes );
}
public static base64URLSafeOfUUIDString( String uuidString ){
    UUID uuid = UUID.fromString( uuidString );
    return UUIDUtil.base64URLSafeOfUUIDObject( uuid );
}
private static long zeroLower48BitsOfLong( long longVar ){
    long upper16BitMask =  -281474976710656L;
    return longVar & upper16BitMask;
}
private static void zeroUpper16BitsOfLong( long longVar ){
    long lower48BitMask =  281474976710656L-1L;
    return longVar & lower48BitMask;
}

}