【问题标题】:How to get binary string from ArrayBuffer?如何从 ArrayBuffer 中获取二进制字符串?
【发布时间】:2013-04-28 02:57:25
【问题描述】:

JavaScript 中从 ArrayBuffer 中获取二进制字符串的方法是什么?

我不想对字节进行编码,只需将二进制表示形式作为字符串。

提前致谢!

【问题讨论】:

  • 我不完全理解您实际上想要完成的转换,您能否进一步解释一下您想要什么?

标签: javascript arraybuffer


【解决方案1】:

以下代码将始终将 ArrayBuffer 转换为 String 并再次转换回来,而不会丢失或添加任何额外的字节。

function ArrayBufferToString(buffer) {
    return BinaryToString(String.fromCharCode.apply(null, Array.prototype.slice.apply(new Uint8Array(buffer))));
}

function StringToArrayBuffer(string) {
    return StringToUint8Array(string).buffer;
}

function BinaryToString(binary) {
    var error;

    try {
        return decodeURIComponent(escape(binary));
    } catch (_error) {
        error = _error;
        if (error instanceof URIError) {
            return binary;
        } else {
            throw error;
        }
    }
}

function StringToBinary(string) {
    var chars, code, i, isUCS2, len, _i;

    len = string.length;
    chars = [];
    isUCS2 = false;
    for (i = _i = 0; 0 <= len ? _i < len : _i > len; i = 0 <= len ? ++_i : --_i) {
        code = String.prototype.charCodeAt.call(string, i);
        if (code > 255) {
            isUCS2 = true;
            chars = null;
            break;
        } else {
            chars.push(code);
        }
    }
    if (isUCS2 === true) {
        return unescape(encodeURIComponent(string));
    } else {
        return String.fromCharCode.apply(null, Array.prototype.slice.apply(chars));
    }
}

function StringToUint8Array(string) {
    var binary, binLen, buffer, chars, i, _i;
    binary = StringToBinary(string);
    binLen = binary.length;
    buffer = new ArrayBuffer(binLen);
    chars  = new Uint8Array(buffer);
    for (i = _i = 0; 0 <= binLen ? _i < binLen : _i > binLen; i = 0 <= binLen ? ++_i : --_i) {
        chars[i] = String.prototype.charCodeAt.call(binary, i);
    }
    return chars;
}

我通过在这个 jsfiddle 中往返以下值来测试它:http://jsfiddle.net/potatosalad/jrdLV/

(String) "abc" -> (ArrayBuffer) -> (String) "abc"
(String) "aΩc" -> (ArrayBuffer) -> (String) "aΩc"
(Uint8Array) [0,1,255] -> (ArrayBuffer) -> (String) -> (Uint8Array) [0,1,255]
(Uint16Array) [0,1,256,65535] -> (ArrayBuffer) -> (String) -> (Uint16Array) [0,1,256,65535]
(Uint32Array) [0,1,256,65536,4294967295] -> (ArrayBuffer) -> (String) -> (Uint32Array) [0,1,256,65536,4294967295]

【讨论】:

  • 谢谢。它从 fileReader.readAsArrayBuffer 和 fileReader.readAsBinaryString 返回什么编码?
  • @aung readAsBinaryString 只是一个 0 和 1 的字符串,基于单个字节到这些的转换。没有“编码”。 readAsArrayBuffer 使用您告诉它的任何掩码(即 Uint8、Uint16、Uint32 等)。
  • ArrayBufferToString() 似乎无法将 ArrayBuffer / Uint8Array 正确转换为二进制字符串。使用 PNG 文件进行测试,添加了一些字节,更改了一些字节。然而,大多数是正确的。我有什么问题吗?我使用 FileReader.readAsArrayBuffer() 读取 PNG 文件,然后将其发送到 ArrayBufferToString()。
【解决方案2】:

近年来添加到 JavaScript 使这变得更加简单 - 这是将 Uint8Array 转换为二进制编码字符串的单行方法:

const toBinString = (bytes) =>
  bytes.reduce((str, byte) => str + byte.toString(2).padStart(8, '0'), '');

例子:

console.log(toBinString(Uint8Array.from([42, 100, 255, 0])))
// => '00101010011001001111111100000000'

如果您从 ArrayBuffer 开始,请创建缓冲区的 Uint8Array“视图”以传递给此方法:

const view = new Uint8Array(myArrayBuffer);
console.log(toBinString(view));

来源:Libauth 库 (binToBinString method)

【讨论】:

    【解决方案3】:

    这将为您提供来自类型化数组的二进制字符串

    var bitsPerByte = 8;
    var array = new Uint8Array([0, 50, 100, 170, 200, 255]);
    var string = "";
    
    function repeat(str, num) {
        if (str.length === 0 || num <= 1) {
            if (num === 1) {
                return str;
            }
    
            return '';
        }
    
        var result = '',
            pattern = str;
    
        while (num > 0) {
            if (num & 1) {
                result += pattern;
            }
    
            num >>= 1;
            pattern += pattern;
        }
    
        return result;
    }
    
    function lpad(obj, str, num) {
        return repeat(str, num - obj.length) + obj;
    }
    
    Array.prototype.forEach.call(array, function (element) {
        string += lpad(element.toString(2), "0", bitsPerByte);
    });
    
    console.log(string);
    

    输出是

    000000000011001001100100101010101100100011111111
    

    开启jsfiddle

    或者你可能在问这个?

    function ab2str(buf) {
        return String.fromCharCode.apply(null, new Uint16Array(buf));
    }
    

    注意:以这种方式使用 apply 意味着您可以达到参数限制(大约 16000 个元素左右),然后您将不得不循环遍历数组元素。

    开启html5rocks

    【讨论】:

    • 这里似乎允许对代码的作用进行一些解释
    【解决方案4】:
    function string2Bin(s) {
      var b = new Array();
      var last = s.length;
      for (var i = 0; i < last; i++) {
        var d = s.charCodeAt(i);
        if (d < 128)
          b[i] = dec2Bin(d);
        else {
          var c = s.charAt(i);
          alert(c + ' is NOT an ASCII character');
          b[i] = -1;
        }
      }
      return b;
    }
    
    function dec2Bin(d) {
      var b = '';
      for (var i = 0; i < 8; i++) {
        b = (d%2) + b;
        d = Math.floor(d/2);
      }
      return b;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      • 2010-11-20
      • 1970-01-01
      • 2020-10-30
      • 1970-01-01
      • 2020-04-05
      相关资源
      最近更新 更多