5

アルゴリズムを使用して、XMLファイルから取得した可変長であるが非常に長い文字列フィールドをエンコードしようとしています。その場合、エンコードされたデータはデータベースに保持されます。

後で、2番目のファイルを受け取ったときに、エンコードされたデータをデータベース(以前に保存されたもの)からフェッチし、それをデコードして、新しいデータで重複を検証する必要があります。

org.apache.commons.codec.binary.Base64私はそれが2つのメソッドを持っているクラスを試しました:

  1. encodeBase64(Byte[] barray)
  2. decodeBase64(String str)

これは完全にうまく機能し、私の問題を解決します。ただし、55文字の文字列を6文字の文字列に変換します。

したがって、これらのアルゴリズムが、非常に大きく、(たとえば)1文字の不一致しかない2つの文字列を同じエンコードされたバイト配列にエンコードする場合があるのではないかと思います。

私はクラスについてあまり知りBase64ませんが、誰かが私を助けることができればそれは本当に役に立ちます。

大きな文字列を固定長より短くし、私の目的を解決する他のアルゴリズムを提案できれば、私はそれを喜んで使用します。

前もって感謝します。

4

2 に答える 2

13

あまり効率的ではありません。

また、sun.miscクラスを使用すると、移植性のないアプリケーションになります。

MiGBase64からの次のパフォーマンス比較を確認してください。

ここに画像の説明を入力


したがって、これらのアルゴリズムが非常に大きく、文字の不一致が 1 つしかない (たとえば) 2 つの文字列を同じエンコードされたバイト配列にエンコードする場合があるのではないかと思います。

Base64 はハッシュ アルゴリズムではなく、エンコーディングであるため、双方向である必要があります。必然的に衝突を許すことはできません。そうしないと、デコードが非決定論的になります。Base64 は、任意のバイナリ データを ASCII 文字列で表すように設計されています。Unicode 文字セットは複数のバイトを必要とするため、Unicode 文字列を Base64 としてエンコードすると、必要なコード ポイントの数が多くなることがよくあります。Unicode 文字列の Base64 表現は、使用されるエンコーディング (UTF-8、UTF-16) によって異なります。例えば:

Base64( UTF8( "test" ) ) => "dGVzdA=="
Base64( UTF16( "test" ) ) => "/v8AdABlAHMAdA=="

解決策 1

無損失圧縮を使用する

GZip( UTF8( "test" ) )

ここでは、文字列をバイト配列に変換し、可逆圧縮を使用して保存する必要があるバイト数を減らしています。文字エンコーディングと圧縮アルゴリズムを変更して、格納する文字列に応じてバイト数を減らすことができます (つまり、ほとんどが ASCII の場合は、UTF-8 がおそらく最適です。

長所: 衝突がなく、元の文字列を復元できる
短所: 値を格納するために必要なバイト数は可変です。値を格納するために必要なバイト数が大きい

解決策 2

ハッシュ アルゴリズムを使用する

SHA256( UTF8( "test" ) )

ここでは、ハッシュ関数を使用して文字列を固定長のバイト セットに変換しています。ハッシュは単方向であり、その性質上、衝突が発生する可能性があります。ただし、処理する予定の文字列のプロファイルと数に基づいて、衝突の可能性を最小限に抑えるハッシュ関数を選択できます。

長所: 値を格納するために必要なバイト数は固定されています。値を格納するために必要なバイト数が少ない
短所: 衝突の可能性があり、元の文字列を復元する機能がない

于 2011-06-15T10:01:38.850 に答える
1

私はちょうどあなたのコメントを見ました-私が最初に考えたように、あなたは実際にはハッシュではなく圧縮を探しているようです. その場合、任意の入力に対して固定長の出力を取得することはできません(考えてみてください。無限の数の入力を有限数の出力に全単射でマッピングすることはできません)。 .

いずれにせよ、選択した圧縮アルゴリズムのパフォーマンスは、入力テキストの特性によって異なります。詳細な情報がない場合、DEFLATE 圧縮 (Zip 入力ストリーム IIRC で使用される) は、最初に使用するのに適した汎用アルゴリズムであり、少なくとも比較の基礎として使用できます。ただし、実装を容易にするために、ZLib 圧縮を使用する JDK に組み込まれている Deflator クラスを使用できます。

入力文字列に特定のパターンがある場合、さまざまな圧縮アルゴリズムが多かれ少なかれ効率的である可能性があります。ある点では、圧縮されたデータを他のプロセスで読み取るつもりがない場合は、どちらを使用してもかまいません。自分で圧縮および解凍できる限り、クライアントに対して透過的です。

これらの他の質問は興味深いかもしれません:

于 2011-06-15T10:02:51.643 に答える