16

私の仕事中のプロジェクトは、Jackson JSONシリアライザーを使用して、RESTサービスに送信するために一連のJavaオブジェクトを文字列に変換しています。

これらのオブジェクトの一部には機密データが含まれているため、これらのオブジェクトをJSON文字列にシリアル化し、gzipで圧縮してから、AES;を使用して暗号化するカスタムシリアライザーを作成しました。

これにより文字列がバイト配列に変換されるため、コーデックのBase64エンコーダーを使用してバイト配列を文字列に変換します。Apache commonsRESTインターフェースの背後にあるカスタムデシリアライザーは、このプロセスを逆にします。

base64 decode -> decrypt -> decompress -> deserialize using default Jackson deserializer.

Base64エンコーディングは出力のサイズを増加させます(シリアル化のgzipステップはこの増加を改善するのに役立つことを目的としています)ので、より効率的な代替手段があるかどうかをGoogleで確認しました。これにより、 Ascii85エンコーディングを次のように起動したこの以前のスタックオーバーフロースレッドにつながりました。より効率的な代替手段-

Base64出力のサイズに33%を追加し、出力のAscii85サイズに25%を追加します。

いくつかのJavaAscii85実装(Apache pdfboxなど)を見つけましたが、エンコーディングを使用するのは少し不安です-誰もそれを使用または実装していないようです。これは、Base64の慣性が大きいことを意味する場合もあれば、代わりにAscii85にはいくつかの奇妙な問題があります。

誰かがこの主題についてもっと知っていますか?Ascii85に問題があり、代わりにBase64を使用する必要がありますか?

4

3 に答える 3

17

Base64 はより一般的ですほとんどの場合、サイズの違いはそれほど重要ではありません。ペイロード内ではなく HTTP レベル (base64 を圧縮します) で追加すると、違いが完全になくなることがあります

代わりに Base64 を使用する必要があることを意味する Ascii85 に関する問題はありますか?

base64 は非常に広く普及しているため、base64 を使用することを強くお勧めします。これは、バイナリ データをテキストとして表現する標準的な方法です (もちろん、16 進数を使用したい場合を除きます)。

于 2012-11-15T21:35:46.010 に答える
8

ASCII85 は、余分なスペースを節約するために使用する優れたエンコーディングです。しかし、単純に HTTP 経由で送信した場合、エスケープする必要がある多くの文字が出力されます。Base64 エンコーディングには、エスケープせずに HTTP 経由で送信できるバリアントがあります。

誰かが試す必要がある場合に備えて、JavaScript ASCII85 エンコーダーを次に示します。

// By Steve Hanov. Released to the public domain.
function encodeAscii85(input) {
  var output = "<~";
  var chr1, chr2, chr3, chr4, chr, enc1, enc2, enc3, enc4, enc5;
  var i = 0;

  while (i < input.length) {
    // Access past the end of the string is intentional.
    chr1 = input.charCodeAt(i++);
    chr2 = input.charCodeAt(i++);
    chr3 = input.charCodeAt(i++);
    chr4 = input.charCodeAt(i++);

    chr = ((chr1 << 24) | (chr2 << 16) | (chr3 << 8) | chr4) >>> 0;

    enc1 = (chr / (85 * 85 * 85 * 85) | 0) % 85 + 33;
    enc2 = (chr / (85 * 85 * 85) | 0) % 85 + 33;
    enc3 = (chr / (85 * 85) | 0 ) % 85 + 33;
    enc4 = (chr / 85 | 0) % 85 + 33;
    enc5 = chr % 85 + 33;

    output += String.fromCharCode(enc1) +
      String.fromCharCode(enc2);
    if (!isNaN(chr2)) {
      output += String.fromCharCode(enc3);
      if (!isNaN(chr3)) {
        output += String.fromCharCode(enc4);
        if (!isNaN(chr4)) {
          output += String.fromCharCode(enc5);
        }
      }
    }
  }

  output += "~>";

  return output;
}
<input onKeyUp="result.innerHTML = encodeAscii85(this.value)" placeholder="write text here" type="text">
<p id="result"></p>

于 2015-04-02T14:45:42.557 に答える
3

JavaScriptで ASCII85 AKA Base85 デコーダー (ユーザーQwerty用) に一致するものを次に示します。

function decode_ascii85(a) {
  var c, d, e, f, g, h = String, l = "length", w = 255, x = "charCodeAt", y = "slice", z = "replace";
  for ("<~" === a[y](0, 2) && "~>" === a[y](-2), a = a[y](2, -2)[z](/\s/g, "")[z]("z", "!!!!!"), 
  c = "uuuuu"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), 
  e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);
  return function(a, b) {
    for (var c = b; c > 0; c--) a.pop();
  }(e, c[l]), h.fromCharCode.apply(h, e);
}
<input onKeyUp="result.innerHTML = decode_ascii85(this.value)" placeholder="insert encoded string here" type="text">
<p id="result"></p>
example: <xmp><~<+oue+DGm>@3BW*D/a<&+EV19F<L~></xmp>

于 2015-07-31T08:11:38.813 に答える