46

I would like to inject binary data into an object in JavaScript. Is there a way to do this?

i.e.

var binObj = new BinaryObject('101010100101011');

Something to that effect. Any help would be great.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742

11 Answers11

30

You can use parseInt:

var bin = parseInt('10101010', 2);

The second argument (the radix) is the base of the input.

Greg
  • 316,276
  • 54
  • 369
  • 333
  • 27
    I feel compelled to point out that this answer is now outdated in 2012. You now have _Typed Arrays_ http://www.khronos.org/registry/typedarray/specs/latest/ Ex: `var arr = Uint8Array(new ArrayBuffer(1000));` – lenkite Apr 27 '12 at 18:22
  • @lenkite - is that a possible extension, or is it something available in most current browsers (consider most users browsers are at the 2/3 years old mark)? – Danny Staple Jul 24 '12 at 15:12
  • 2
    @DannyStaple - available in an encouraging number of today's browsers, apart from (of course) IE: http://caniuse.com/#feat=typedarrays – chrisfrancis27 Aug 30 '12 at 10:14
  • Hmm - any chances of a version of IE with that on the horizon? – Danny Staple Aug 30 '12 at 12:53
  • It is important to note that Android <4 also doesn't support TypedArrays. This a pretty important platform. – dalgard Mar 22 '13 at 23:07
  • @lenkite Note that whilst the `TypedArray` is indeed useful for storing binary data, it in no way helps with the _conversion_ of ASCII binary strings into raw data buffers. – Alnitak Aug 31 '13 at 14:05
  • if it still works, then its not outdated, am i right? – Elon Zito Mar 18 '16 at 16:49
23

There's this binary ajax library that is explained here and there's also another binary parser library that can handle more data types.

You could also look at Google Gears which has a binary Blob object or take a look at making a javascript wrapper for Flash which provides a native ByteArray implementation.

Or... you can sit and wait and hope that all these things become standard :)

RandomEtc
  • 1,976
  • 1
  • 18
  • 17
  • 2
    These links no longer work... I would recommend newer jBinary library: https://github.com/jDataView/jBinary – zippy Dec 18 '14 at 22:31
16

On all recent browsers you can do:

xhr.overrideMimeType('text/plain; charset=x-user-defined');

And retrieve a string. To get the binary result you will have to do

data.charCodeAt(pos) & 0xff;

On the nightly builds of Firefox and Chrome you can retrieve the value as an ArrayBuffer

xhr.responseType = "arraybuffer";

The result is then accessible there

xhr.mozResponseArrayBuffer // Firefox
xhr.response // Chrome

Then you can apply a TypedArray (eg: Int32Array) or a DataView on the buffer to read the result.


In order to make this process easier, I made a jQuery Patch to support the binary type and a DataView Wrapper that uses the latest available reading feature of the browser.

Vjeux
  • 5,756
  • 4
  • 31
  • 24
  • can you maybe clarify how to get the binary data as a string, my firefox always ends at the line 'xhr.reponstype ="arraybuffer";' – Gobliins May 24 '12 at 08:59
  • Are you sure this works? My unicode sense is tingling. Unicode characters are sometimes more than one byte long. – Hoffmann Feb 26 '15 at 21:05
11

JavaScript has very little support for raw binary data. In general, it's best to live within this restriction. However, there's a trick I'm considering trying for a project of mine that involves manipulating huge bitmaps to do set operations in an OLAP database. This won't work in IE.

The basic idea is this: coerce the binary data into a PNG to send it to JavaScript, For example, a bitmap might be a black and white PNG, with black being 100% transparent. Then use Canvas operations to do bitwise data manipulation.

The HTML5 Canvas includes a pixel array type, which allows access to bytes in an image. Canvas also supports compositing operations, such as XOR. Lighten and darken should be able to do AND and OR. These operations are likely to be well optimized in any browser that supports them-- probably using the GPU.

If anyone tries this, please let me know how well it works.

David Leppik
  • 3,194
  • 29
  • 18
  • 3
    When you are using HTML5 canvas, try using processingJS library. They have lots of useful utility functions. – Thejesh GN Nov 16 '09 at 06:35
2

As @Zippy pointed out in a comment, the more recent (late 2016) solutions include:

Brian M. Hunt
  • 81,008
  • 74
  • 230
  • 343
2

That would be the other way around... pow and squareroot might be calculated by the Math-Class... I don't know if it is the fastest way, but it's as fast as the Windows Calculator in the "Programmer View".

AlertFormatedBin();
function AlertFormatedBin()
{
    var vals = decToBinArr(31,8);
    var i;

    var s = "";
    var mod = vals.length % 4;
    for(i= 0; i <mod;i++)
    {
        s+=vals[i];
    }
    if(i>0)
        s+=" ";
    var j = i;
    for(i;i<vals.length;i++)
    {
        s+=vals[i];
        if(i-j != 0 && (i+1-j)%4 == 0)
        {
            s+=" ";
        }
    }
    alert(s);
}

function decToBinArr(dec, minSize)
{
    var mod = dec%2;
    var r = new Array();
    if(dec > 1)
    {
        dec-=mod;
        var bd = squareRootRoundedDown(dec);
        if(minSize && minSize-1 > bd)
            bd = minSize-1;
        else
            var i;
            for(i = bd; i>0;i--)
            {
                var nxt = pow(2,i);
                if(dec >= nxt)
                {
                    r[i] = 1;
                    dec-=nxt;
                }
                else
                {
                    r[i] = 0;
                }
            }
    }
    r[0]= mod;
    r.reverse();
    return r;
}

function squareRootRoundedDown(dec)
{
    if(dec<2)
        return 0;
    var x = 2;
    var i;
    for(i= 1;true;i++)
    {
        if(x>=dec)
        {
            i = x == dec ? i : i-1;
            break;
        }
        x= x*2;
    }
    return i;
}

function pow(b,exp)
{
    if(exp == 0)
        return 0;
    var i = 1;
    var r= b;
    for(i = 1; i < exp;i++)
        r=r*b;
    return r;
}
stealthyninja
  • 10,343
  • 11
  • 51
  • 59
Frithjof
  • 21
  • 2
2

In the near future you will be able to use ArrayBuffers and File API Blobs.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
GGG
  • 21
  • 1
1

jBinary "makes it easy to create, load, parse, modify and save complex binary files and data structures in both browser and Node.js."

I haven't used it, but it's what I found when asking the same question asked here...

zippy
  • 1,228
  • 10
  • 19
1

Javascript doesn't provide a mechanism to load an object in any form other than simple strings.

Closest you can do is serializing the object to a string, optionally encrypting/compressing it, sending it to the browser, and decrypting/decompressing if necessary, checking for sanity, eval() and pray().

Instead of using eval (which is not quite safe), you can use your own format (alternatively, xml or json for which there are plenty of libs) and parse it yourself.

As a side note, if you want this for obfuscation after the browser gets the usable data (after decrypting/decompressing), it is too easy to circumvent.

artificialidiot
  • 5,309
  • 29
  • 27
1

Welcome to everyone who found this older post on Google. I figured out a solution that works in Chrome as of 2019, so hopefully this is just some added feature or something most people missed.

You can use a 0b prefix to your number. It won't quite get the binary representation, but you can easily convert it to an integer for storage. For example, you could store the binary number 1010 as such:

var binNum = 0b1010 //Stores as an integer, which would be 10

If you're curious, it also works for hexadecimal with the 0x prefix:

var binNum = 0x1010 //Stores as an integer, which would be 4112
1

Percent encoding can unescape strings into a direct 1<->1 representaion of any binary blob and is also portable across browsers;

unescape("%uFFFF%uFFFF%uFFFF");

Most browser exploit's use this technique for embedding shellcode into HTML pages, it works very well for creating arbitrary binary streams.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
RandomNickName42
  • 5,923
  • 1
  • 36
  • 35