2011-07-07 13 views
3

膨大な数のUUIDをxml互換の文字列に変換する必要があります。 Base62アルゴリズム(各5ビットを32文字のいずれかにマップする)を使用すると、Base62アルゴリズム(反復して128ビット整数を62で割り算し、モジュラスを62文字の1つとして記録する場合、26文字の文字列になります) )これは22文字の文字列につながります。 base62はより短い文字列を返しますが、CPU使用量がはるかに多いため、Base32(Base64はxmlのためにオプションではありません)に固執しています。UUIDS(Base32、Base62など)をエンコードする従来のアルゴリズムの代替方法

ここで私たちを助けてくれる他のタイプのエンコードアルゴリズムをご存知ですか? 2の累乗ではないベースで使用できるBase32のようなビットパターンエンコーディングアルゴリズムのバリエーションがありますか?または、第1アルゴリズムのアプローチと第2アルゴリズムのアプローチを組み合わせたハイブリッドアルゴリズムがありますか?可能であれば、文字列を26未満に減らしたいと考えています。

答えて

3

あなたはアルファベットをA〜Z(大文字と小文字)と数字の0〜9に制限していることを示唆しました。そのリストにXML互換の文字をもう1つ追加しないでください。たとえば、+,.~、または!などの数字を64に設定するとどうなりますか?ディビジョンではなくビットシフトを行うことができます。これは、アルゴリズムをBase32のアルゴリズムと同じくらい速くし、文字列サイズを小さくするはずです。

編集:これらの文字は、他のとしてまだ未指定の言語で使用可能な制限以来は、あなたの64個のオプションを表現するために、あなたの文字の一部をエスケープする気かもしれません。たとえば_をエスケープ文字として使用すると、_1と_2はオプション63と64を表します。元の質問にはUUIDSが128ビットであることが示されているので、Base64は22文字を返しますエスケープされず、4つまでの項目がエスケープされた場合、26文字以内に保持されます。

+1

'_'と' -' –

+0

良い点もありますして保存し、あなたに感謝!しかし、XMLは私たちの唯一の制限ではなく、いくつかのプログラミング言語でクラス名を生成するためにも使用する必要があります(アンダースコアは別の文字ですが、64番目の使用可能なASCII文字は見つかりませんでした)。 – Alexander233

+0

@キャリーナ - 私はあなたが文字を使い果たした場合に役立つかもしれない提案を追加しました。もしあなたができるならば、余分な64番目のキャラクターを見つけることが最善でしょう。 – borrible

0

Wikipediaは、XML名前空間で使用できるBase64の2つのバージョンを提供しています。

http://en.wikipedia.org/wiki/Base64#XML。私はJavaでURLSafe、UUIDを行うために以下のJAVAを書いています(theObjectReturned.toString()を呼び出してguid文字列として取得します)。

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

コードは、次のとおりです。

私は非常に高速であるために仮定され、簡単にXML安全な変種を行うように変更することができ、Java用の他のコードを見てきました。 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; 
} 

}

+1

非常に興味深い。しかし、XMLで言及しているアプローチの問題は、要素名が数字で始まらず、 'xml'または 'XML'で始まらないことです。 Wikipediaの記事のアプローチとbase64URLSafeOfUUIDObjectの両方で、これらの要件に一致しないエンコーディングが発生します。 – Alexander233

+0

私はUUIDジェネレータの出力を要素の名前に使用することは考えず、要素のデータだけを考えました。あなたは私にその事例を教えてもらえますか?私の好奇心と覚醒を満足させるだけですか? :-) – Dennis