How do I implement hex2bin()?
Asked Answered
E

10

27

I need to communicate between Javascript and PHP (I use jQuery for AJAX), but the output of the PHP script may contain binary data. That's why I use bin2hex() and json_encode() on PHP side.

How do I convert the hexadecimal string in binary string, with JavaScript?

Electronarcosis answered 8/10, 2011 at 7:38 Comment(1)
@MartyIX: Here is a BSD-licensed Javascript function that does what you want.Cannelloni
L
18

JavaScript doesn't have support for binary data. Nevertheless you can emulate this with regular strings.

var hex = "375771", // ASCII HEX: 37="7", 57="W", 71="q"
    bytes = [],
    str;

for(var i=0; i< hex.length-1; i+=2){
    bytes.push(parseInt(hex.substr(i, 2), 16));
}

str = String.fromCharCode.apply(String, bytes);

alert(str); // 7Wq
Lingulate answered 8/10, 2011 at 7:53 Comment(1)
when this answer was written, it was probably correct, but JS does support binary data now, with the Uint8Array :) it's very cubersome to use compared to php's binary strings which essentially are Uint8Array's already, but it's better than nothing ¯\_(ツ)_/¯Aureus
S
61

To answer your question:

function Hex2Bin(n){if(!checkHex(n))return 0;return parseInt(n,16).toString(2)}

Here are some further functions you may find useful for working with binary data:

//Useful Functions
function checkBin(n){return/^[01]{1,64}$/.test(n)}
function checkDec(n){return/^[0-9]{1,64}$/.test(n)}
function checkHex(n){return/^[0-9A-Fa-f]{1,64}$/.test(n)}
function pad(s,z){s=""+s;return s.length<z?pad("0"+s,z):s}
function unpad(s){s=""+s;return s.replace(/^0+/,'')}

//Decimal operations
function Dec2Bin(n){if(!checkDec(n)||n<0)return 0;return n.toString(2)}
function Dec2Hex(n){if(!checkDec(n)||n<0)return 0;return n.toString(16)}

//Binary Operations
function Bin2Dec(n){if(!checkBin(n))return 0;return parseInt(n,2).toString(10)}
function Bin2Hex(n){if(!checkBin(n))return 0;return parseInt(n,2).toString(16)}

//Hexadecimal Operations
function Hex2Bin(n){if(!checkHex(n))return 0;return parseInt(n,16).toString(2)}
function Hex2Dec(n){if(!checkHex(n))return 0;return parseInt(n,16).toString(10)}
Shawm answered 20/10, 2012 at 9:22 Comment(6)
This doesn't seem to be working with actual binary data, rather with ASCII representations of binary data.Fortyfive
Your functions are wrong. At least Hex2Bin and Bin2Hex. Didn't even try other afterI got wrong results with those two. Try yourself Hex2Bin => Bin2HexSedda
I've been using this set for a long time. And I am beginning to use Hex2Bin and realized it just now. Hex2Bin is broken. I think Bin2Hex is also wrong.Colliery
For the two functions, here is one that works: #17205412Colliery
It depends if you mean 1 bit binary representation (0/1) or 8 bit binary representation (bytes of data). In this answer "bin" means base 2 (binary 1s and 0s)Dorena
Your Hex2Bin function doesn't work for anything longer than a single pair of hex values.Shredding
L
18

JavaScript doesn't have support for binary data. Nevertheless you can emulate this with regular strings.

var hex = "375771", // ASCII HEX: 37="7", 57="W", 71="q"
    bytes = [],
    str;

for(var i=0; i< hex.length-1; i+=2){
    bytes.push(parseInt(hex.substr(i, 2), 16));
}

str = String.fromCharCode.apply(String, bytes);

alert(str); // 7Wq
Lingulate answered 8/10, 2011 at 7:53 Comment(1)
when this answer was written, it was probably correct, but JS does support binary data now, with the Uint8Array :) it's very cubersome to use compared to php's binary strings which essentially are Uint8Array's already, but it's better than nothing ¯\_(ツ)_/¯Aureus
R
10
function hex2bin(hex)
{
    var bytes = [], str;

    for(var i=0; i< hex.length-1; i+=2)
        bytes.push(parseInt(hex.substr(i, 2), 16));

    return String.fromCharCode.apply(String, bytes);    
}

thanks to Andris!


Other useful information about this topic (dex2bin,bin2dec) can be found here. According to that, here is a bin2hex solution:

parseInt(1100,2).toString(16); //--> c
Rupp answered 28/3, 2012 at 14:22 Comment(0)
F
5

Although not an answer to the actual question, it is perhaps useful in this case to also know how to reverse the process:

function bin2hex (bin)
{

  var i = 0, l = bin.length, chr, hex = ''

  for (i; i < l; ++i)
  {

    chr = bin.charCodeAt(i).toString(16)

    hex += chr.length < 2 ? '0' + chr : chr

  }

  return hex

}

As an example, using hex2bin on b637eb9146e84cb79f6d981ac9463de1 returns ¶7ëFèL·mÉF=á, and then passing this to bin2hex returns b637eb9146e84cb79f6d981ac9463de1.

It might also be useful to prototype these functions to the String object:

String.prototype.hex2bin = function ()
{

  var i = 0, l = this.length - 1, bytes = []

  for (i; i < l; i += 2)
  {
    bytes.push(parseInt(this.substr(i, 2), 16))
  }

  return String.fromCharCode.apply(String, bytes)   

}

String.prototype.bin2hex = function ()
{

  var i = 0, l = this.length, chr, hex = ''

  for (i; i < l; ++i)
  {

    chr = this.charCodeAt(i).toString(16)

    hex += chr.length < 2 ? '0' + chr : chr

  }

  return hex

}

alert('b637eb9146e84cb79f6d981ac9463de1'.hex2bin().bin2hex())
Fortyfive answered 14/3, 2013 at 9:53 Comment(1)
bin2hex seems really inefficient (and slow) if I want to, say, convert a large image file into a hex string...Fortyfive
M
3

All proposed solutions use String.fromCharCode, why not simply using unescape?

String.prototype.hex2bin = function()
{ 
   var i = 0, len = this.length, result = "";

   //Converting the hex string into an escaped string, so if the hex string is "a2b320", it will become "%a2%b3%20"
   for(; i < len; i+=2)
      result += '%' + this.substr(i, 2);      

   return unescape(result);
}

and then:

alert( "68656c6c6f".hex2bin() ); //shows "hello"
Mesh answered 14/6, 2013 at 17:53 Comment(2)
why not simply using unescape - Just because it's deprecated. ;)Chlorophyll
you can use decodeURIComponent instead of unescape and this is perfectly fine. However thanks @Marco, I used your solutionRoadside
J
3

With reference to node.js ( not in browser ).

Basically it's all over-engineered and does not work well.

responses are out of alignment and though text-wise they are the same bit wise everything is all over the place :

curl http://phpimpl.domain.com/testhex.php | xxd

00000000: de56 a735 4739 c01d f2dc e14b ba30 8af0  .Q.%G9.....;.0..

curl http://nodejs.domain.com/ | xxd

00000000: c39e 56c2 a725 4739 c380 c3ad c3b1 c39c  ..Q..%G9........
00000010: c3a1 37c2 6b30 c28f c3b0                 ..;..0....

The proper way to implement this in node is :

function hex2bin(hex){
   return new Buffer(hex,"hex");
}


curl http://nodejs.domain.com/ | xxd

00000000: de56 a735 4739 c01d f2dc e14b ba30 8af0  .Q.%G9.....;.0..

Hope this helps.

Johnnyjumpup answered 6/5, 2016 at 16:2 Comment(0)
T
1

Here is an implementation of hex2bin in JS that takes a string and returns Uint8Array, works both in browsers and nodejs,

function hex2bin(hex) {
  var length = hex.length / 2;
  var result = new Uint8Array(length);
  for (var i = 0; i < length; ++i) {
    result[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
  }
  return result;
}

And its inverse,

function bin2hex(bin) {
  return Array.from(bin).map(function (x) {
    return x.toString(16).padStart(2, '0');
  }).join('');
}
Thad answered 5/12, 2020 at 19:10 Comment(0)
U
0

String.prototype.hex2bin = function () {
    if (this.length % 2 !== 0) return false;

    let bytes = []
    for (let i = 0; i < this.length - 1; i += 2) {
        let charCode = parseInt(this.substring(i, i + 2), 16)
        bytes.push(charCode)
    }

    return String.fromCharCode.apply(String, bytes)
        .replace(/\x00+$/g, '') // not necessary
        .trim()
}
    
console.log('78534F4C41527800000000000000000000000000'.hex2bin()) // xSOLARx (length: 7)
console.log('4D554C5449504153530000000000000000000000'.hex2bin()) // MULTIPASS (length: 9)
console.log('4C5A415200000000000000000000000000000000'.hex2bin()) // LZAR (length: 4)
Uneasy answered 30/4, 2023 at 13:0 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Bestialize
C
-1

JavaScript does actually contain support for binary data. See Uint8Array.

Just read each byte from the array and convert it into hexadecimal.

Cotillion answered 13/1, 2013 at 0:31 Comment(0)
H
-1

If someone needs the other direction (bin to hex), here is it:

function bin2hex(bin) {
    return new Buffer(bin).toString("hex");
}
Homelike answered 19/3, 2018 at 11:20 Comment(1)
Uncaught ReferenceError: Buffer is not definedDorena

© 2022 - 2024 — McMap. All rights reserved.