如何在JavaScript中进行ASCII85编码/解码

7
我正在寻找一个替代Base64的方案,它可以很好地处理Unicode字符。我已经发现ASCII85非常好用,但是我没有在JS中找到任何代码或命令来实现这一点。
我刚刚找到了this link,它不能处理国际字符并且不包括解码函数。
这里有在线Decoder/Encoder
甚至在C语言中也找到了codes来实现这一点(我没有足够的JS数据处理知识来转换)。
还有一些codes,我不知道如何运行。
我听说 JQuery 支持 Base64,但好像不支持 Ascii85
有人知道 JS 中与 Ascii85 相关的信息吗?
谢谢。

1
问题是,为什么你需要Base64,而UTF-8不够好? - adeneo
UTF-8或任何标准编码有什么问题吗? - Precastic
我使用ASCII85而不是直接访问字符串数组。这比混淆更好。这不是安全问题,而是数据权利问题。 - gerrnar
4个回答

9

纯JavaScript Ascii85(也称为Base85)编码/解码函数:

function encode_ascii85(a) {
  var b, c, d, e, f, g, h, i, j, k;
  for (!/[^\x00-\xFF]/.test(a), b = "\x00\x00\x00\x00".slice(a.length % 4 || 4), a += b, 
  c = [], d = 0, e = a.length; e > d; d += 4) f = (a.charCodeAt(d) << 24) + (a.charCodeAt(d + 1) << 16) + (a.charCodeAt(d + 2) << 8) + a.charCodeAt(d + 3), 
  0 !== f ? (k = f % 85, f = (f - k) / 85, j = f % 85, f = (f - j) / 85, i = f % 85, 
  f = (f - i) / 85, h = f % 85, f = (f - h) / 85, g = f % 85, c.push(g + 33, h + 33, i + 33, j + 33, k + 33)) :c.push(122);
  return function(a, b) {
    for (var c = b; c > 0; c--) a.pop();
  }(c, b.length), "<~" + String.fromCharCode.apply(String, c) + "~>";
}

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);
}

var myString='This is a test!';
var encoded=encode_ascii85(myString);
var decoded=decode_ascii85(encoded);
document.write(decoded);


3
这个例子无法恢复Unicode文本:表情符号,西里尔字母至少。 - Pavel Vlasov
它在处理二进制字符串时不正确,在长字符串(65k+个字符)上也如此。 - KeyKi

3

这与我在其中一个链接中提到的相同。但是如何使用它? - gerrnar
看起来你的例子是关于 HTML 实体编码而不是 ASCII85 编码! - gerrnar
你是正确的,这就是通常使用编码的方法。 看这个链接,他使用了相同的框架(他使用的编码是ascii85) https://bitbucket.org/Crisu83/invaders/src/e49caaad10eb/js/lib/dojox/encoding/tests/compression/colors2.html - Muath

1

在此添加更多描述 - Mathews Sunny

0

对于那些想要一个口语化版本的Dave Brown的答案(从他的答案中反向工程并测试得出)的人:

function encode_ascii85(sSource) {
    var sSuffix, iStringLength, f;
    var charArray = [];

    if (!/[^\x00-\xFF]/.test(sSource)) {
        [sSource, sSuffix, iStringLength] = initForLoop(sSource);

        for (var iIndex = 0; iStringLength > iIndex; iIndex += 4) {
            f = (sSource.charCodeAt(iIndex) << 24) + (sSource.charCodeAt(iIndex + 1) << 16);
            f = f + (sSource.charCodeAt(iIndex + 2) << 8) + sSource.charCodeAt(iIndex + 3);

            appendNextChar(f, charArray);
        }
        (function truncate(oArray, b) {
            for (var m = b.length; m > 0; m--) oArray.pop();
        })(charArray, sSuffix);

        return "<~" + String.fromCharCode.apply(String, charArray) + "~>";
    } else {
        // Error Handling
    }

    function initForLoop(a) {
        var sSuffix = "\x00\x00\x00\x00".slice(a.length % 4 || 4);
        return [a += sSuffix, sSuffix, a.length];
    }

    function appendNextChar(f, oArray) {
        if (f === 0) {
            oArray.push(122);
        } else {
            var g, h, i, j, k;
            k = f % 85, f = (f - k) / 85;
            j = f % 85, f = (f - j) / 85;
            i = f % 85, f = (f - i) / 85;
            h = f % 85, f = (f - h) / 85;
            g = f % 85;
            oArray.push(g + 33, h + 33, i + 33, j + 33, k + 33);
        }
    }
}

function decode_ascii85(sSource) {
    var sSuffix, d, iStringLength;
    var charArray = [];

    if ("<~" === sSource.slice(0, 2) && "~>" === sSource.slice(-2)) {
        sSource = initForLoop(sSource);

        for (var iIndex = 0; iStringLength > iIndex; iIndex += 5) {
            var x = "charCodeAt";
            var w = 255;

            d = 85 * 85 * 85 * 85 * (sSource[x](iIndex) - 33) + 85 * 85 * 85 * (sSource[x](iIndex + 1) - 33);
            d = d + 85 * 85 * (sSource[x](iIndex + 2) - 33) + 85 * (sSource[x](iIndex + 3) - 33) + (sSource[x](iIndex + 4) - 33);

            charArray.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);
        }
        (function truncate(oArray, b) {
            for (var m = b.length; m > 0; m--) oArray.pop();
        })(charArray, sSuffix);

        return String.fromCharCode.apply(String, charArray);
    } else {
        // Error Handling
    }

    function initForLoop(a) {
        var z = "replace",
            y = "slice";

        a = a[y](2, -2)[z](/\s/g, "")[z]("z", "!!!!!");
        sSuffix = "uuuuu" [y](a.length % 5 || 5);
        a += sSuffix;
        iStringLength = a.length;

        return a;
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接