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



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

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

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

Edit:由于这些字符也可用于其他尚未指定的语言的限制,您可能需要转义一些字符来表示您的64个选项。例如,如果使用_作为转义字符,则可以使用_1和_2表示选项63和64。原始问题中提到的统计数据表明uuid是128位的,因此如果没有转义,我们的Base64将为我们提供22个字符,并且在转义最多4项的情况下,保持在26个字符内。

Wikipedia提供了两个可用于XML名称空间的Base64版本。

http://en.wikipedia.org/wiki/Base64 XML。我写了下面的JAVA来做URLSafe, JAVA中的uuid,(调用objectreturnd . tostring()来获得它作为一个guid字符串)。

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

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

代码。保存在名为uidutil .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;
}

}

相关内容

最新更新