Как получить двоичную строку из ArrayBuffer?

Как получить двоичную строку из ArrayBuffer в JavaScript?

Я не хочу кодировать байты, просто получаю двоичное представление в виде строки.

Заранее спасибо!


person Orest    schedule 03.05.2013    source источник
comment
Я не совсем понимаю, какое преобразование вы на самом деле пытаетесь выполнить, можете ли вы дать дополнительные пояснения, чтобы уточнить, что вы хотите?   -  person Xotic750    schedule 03.05.2013


Ответы (3)


Следующий код последовательно преобразует 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]
person potatosalad    schedule 03.05.2013
comment
Спасибо. Какую кодировку он возвращает из fileReader.readAsArrayBuffer и fileReader.readAsBinaryString? - person aung; 25.08.2017
comment
@aung readAsBinaryString - это просто строка из 0 и 1, основанная на преобразовании отдельных байтов в них. Там нет кодировки. readAsArrayBuffer использует любую маску, которую вы ему укажете (например, Uint8, Uint16, Uint32 и т. д.). - person vapcguy; 04.04.2018
comment
ArrayBufferToString(), похоже, неправильно преобразует ArrayBuffer/Uint8Array в двоичную строку. Тестирование с файлом PNG и некоторые байты добавлены, некоторые изменены. Однако большинство правы. Я что-то не так? Я прочитал файл PNG с помощью FileReader.readAsArrayBuffer(), а затем отправил его в ArrayBufferToString(). - person StanE; 10.06.2021

Это стало намного проще благодаря дополнениям к 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)

person Jason Dreyzehner    schedule 05.06.2020

Это даст вам двоичную строку из типизированного массива

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

person Xotic750    schedule 03.05.2013
comment
здесь дается некоторое объяснение того, что делает код - person Muhammad Umer; 07.05.2021