Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get binary string from ArrayBuffer?

What is the way to obtain binary string from ArrayBuffer in JavaScript?

I don't want to encode the bytes, just get the binary representation as String.

Thanks in advance!

like image 629
Orest Avatar asked May 03 '13 16:05

Orest


People also ask

Is ArrayBuffer a binary?

The ArrayBuffer is a data type that is used to represent a generic, fixed-length binary data buffer.

Is ArrayBuffer same as buffer?

1. A Buffer is just a view for looking into an ArrayBuffer . A Buffer , in fact, is a FastBuffer , which extends (inherits from) Uint8Array , which is an octet-unit view (“partial accessor”) of the actual memory, an ArrayBuffer .

What is ArrayBuffer in JavaScript?

The ArrayBuffer object is used to represent a generic, fixed-length raw binary data buffer. It is an array of bytes, often referred to in other languages as a "byte array".


3 Answers

The following code will consistently convert an ArrayBuffer to a String and back again without losing or adding any additional bytes.

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

I tested it by round-tripping the following values in this 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]
like image 51
potatosalad Avatar answered Sep 19 '22 08:09

potatosalad


This has been made much simpler by additions to JavaScript in recent years – here's a one-line method to convert a Uint8Array into a binary-encoded string:

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

Example:

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

If you're starting with an ArrayBuffer, create a Uint8Array "view" of the buffer to pass into this method:

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

Source: the Libauth library (binToBinString method)

like image 25
Jason Dreyzehner Avatar answered Sep 20 '22 08:09

Jason Dreyzehner


This will give you a binary string from a typed array

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

Output is

000000000011001001100100101010101100100011111111

On jsfiddle

Or perhaps you are asking about this?

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

Note: that using apply in this manner means that you can hit the argument limitation (some 16000 elements or so), and then you will have to loop through the array elements instead.

On html5rocks

like image 39
Xotic750 Avatar answered Sep 18 '22 08:09

Xotic750