我们需要将大量的UUIDS转换为xml兼容的字符串。如果我们使用Base32算法(将每个5位映射到32个字符中的一个),这将导致26个字符串,如果我们使用Base62算法(迭代地将128位整数除以62并将模数记录为62个字符之一)这导致22个字符串。虽然base62返回更短的字符串,但它更加cpu密集,因此我们坚持使用Base32(由于xml,Base64不是一个选项)。
您是否知道可以帮助我们的任何其他类型的编码算法?是否存在类似Base32的位模式编码算法的变体,可以与不是2的幂的基数一起使用?或者是否有混合算法将第一种方法与第二种算法的方法结合起来?如果可能的话,我们希望将char字符串减少到少于26。
答案 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;
}
}