98

How to convert from Hex string to ASCII string in JavaScript?

Ex:

32343630 it will be 2460

Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
Q8Y
  • 3,801
  • 12
  • 39
  • 38
  • 8
    I'm sure there's a jQuery plugin for that ^^ – AndiDog Sep 19 '10 at 12:35
  • 2
    jQuery is primarily meant for DOM manipulation and to a lesser extent, reimplementing things like `Array.prototype.{map,forEach}()` for outdated/limited browsers. Honestly this seems more like [Underscore.js's](http://underscorejs.org/) realm. – Chinoto Vokro Sep 07 '16 at 16:30
  • 1
    @AndiDog Not useful for those of us using node – Adam Fowler Oct 23 '17 at 21:53

10 Answers10

187
function hex2a(hexx) {
    var hex = hexx.toString();//force conversion
    var str = '';
    for (var i = 0; i < hex.length; i += 2)
        str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    return str;
}
hex2a('32343630'); // returns '2460'
ntoonio
  • 3,024
  • 4
  • 24
  • 28
Delan Azabani
  • 79,602
  • 28
  • 170
  • 210
  • 2
    This does not work. `console.log(hex2a('32343630') === hex2a('3234363000')); // returns 'true'!!!`. – steinybot Jun 04 '20 at 10:56
  • 6
    This answer is wrong due to: `&& hex.substr(i, 2) !== '00'`. As @steinybot noticed, this aborts on the first `0` and therefore does not completely convert hex to string. The correct solution is: `function hex2a(hexx) { var hex = hexx.toString();//force conversion var str = ''; for (var i = 0; i < hex.length; i += 2) str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); return str; }` – Marc Wäckerlin Jul 07 '20 at 11:00
  • The [edit history](https://stackoverflow.com/review/suggested-edits/19350946) shows that the `NUL` defect was added on purpose. This answer has been damaged. – Don Cruickshank Jul 18 '20 at 11:39
  • Hey I did the same thing but unfortunately. I am stuck with a problem. The first 2 characters are read and added to the str. But Something happens in the third character and no more character could be added to the string. I logged the iteration and see something like this i:1 M i:2 MZ i:3 MZDCS i:4 MZDCS This DCS is a black boxed character in Notepad++ – gunescelil Mar 28 '23 at 14:11
52

Another way to do it (if you use Node.js):

var input  = '32343630';
const output = Buffer.from(input, 'hex');
log(input + " -> " + output);  // Result: 32343630 -> 2460
Dutchdev
  • 47
  • 7
0x8BADF00D
  • 7,138
  • 2
  • 41
  • 34
39

For completeness sake the reverse function:

function a2hex(str) {
  var arr = [];
  for (var i = 0, l = str.length; i < l; i ++) {
    var hex = Number(str.charCodeAt(i)).toString(16);
    arr.push(hex);
  }
  return arr.join('');
}
a2hex('2460'); //returns 32343630
michieljoris
  • 621
  • 6
  • 4
  • 3
    A note on this implementation: you must manually insert a "0" when the `hex` value is between 0x0 and 0x9. For this, I change your `arr.push(hex)` to `arr.push(hex.length > 1 && hex || "0" + hex);`. – Beterraba May 16 '14 at 19:25
  • String concatenation is actually faster than string array construction and joining in javascript – Mala Jul 11 '14 at 20:53
  • 1
    You have a typo, you forgot to put the closing parenthesis after `toString(16)` (line no. 4). ;-) – Arjun Dec 07 '15 at 11:07
26

You can use this..

var asciiVal = "32343630".match(/.{1,2}/g).map(function(v){
      return String.fromCharCode(parseInt(v, 16));
    }).join('');
    
document.write(asciiVal);
Sampath Liyanage
  • 4,776
  • 2
  • 28
  • 40
13

** for Hexa to String**

let input  = '32343630';

Note : let output = new Buffer(input, 'hex'); // this is deprecated

let buf = Buffer.from(input, "hex");
let data = buf.toString("utf8");
Pascal Belloncle
  • 11,184
  • 3
  • 56
  • 56
mathad
  • 171
  • 1
  • 6
  • 3
    Not sure why this was downvoted, seems to me that's the best answer now for nodejs in 2020 – Pascal Belloncle Jun 04 '20 at 03:33
  • @PascalBelloncle I agree that this is the best answer for Node.js but the problem is that `Buffer` doesn't exist in regular JavaScript. I expect the downvote was because the question is tagged with JavaScript and not Node.js. – Don Cruickshank Jul 18 '20 at 13:48
  • What do you mean it does not exist in regular JS @DonCruickshank – Daniel Tkach Jul 23 '21 at 21:28
  • @DanielTkach By regular JavaScript I meant common browsers. `Buffer.from("414243", "hex")` works on Node.js but it fails on Edge and Firefox as `Buffer` is not defined. – Don Cruickshank Jul 24 '21 at 21:34
10

I found a useful function present in web3 library.

var hexString = "0x1231ac"
string strValue = web3.toAscii(hexString)

Update: Newer version of web3 has this function in utils

The functions now resides in utils:

var hexString = "0x1231ac"
string strValue = web3.utils.hexToAscii(hexString)
Ayushya
  • 9,599
  • 6
  • 41
  • 57
4

console.log(

"68656c6c6f20776f726c6421".match(/.{1,2}/g).reduce((acc,char)=>acc+String.fromCharCode(parseInt(char, 16)),"")

)
Zibri
  • 9,096
  • 3
  • 52
  • 44
3

I've found that the above solution will not work if you have to deal with control characters like 02 (STX) or 03 (ETX), anything under 10 will be read as a single digit and throw off everything after. I ran into this problem trying to parse through serial communications. So, I first took the hex string received and put it in a buffer object then converted the hex string into an array of the strings like so:

buf = Buffer.from(data, 'hex');
l = Buffer.byteLength(buf,'hex');
for (i=0; i<l; i++){

    char = buf.toString('hex', i, i+1);
    msgArray.push(char);

}

Then .join it

message = msgArray.join('');

then I created a hexToAscii function just like in @Delan Azabani's answer above...

function hexToAscii(str){
    hexString = str;
    strOut = '';
        for (x = 0; x < hexString.length; x += 2) {
            strOut += String.fromCharCode(parseInt(hexString.substr(x, 2), 16));
        }
    return strOut;    
}

then called the hexToAscii function on 'message'

message = hexToAscii(message);

This approach also allowed me to iterate through the array and slice into the different parts of the transmission using the control characters so I could then deal with only the part of the data I wanted. Hope this helps someone else!

kumar kundan
  • 2,027
  • 1
  • 27
  • 41
1

An optimized version of the implementation of the reverse function proposed by @michieljoris (according to the comments of @Beterraba and @Mala):

function a2hex(str) {
  var hex = '';
  for (var i = 0, l = str.length; i < l; i++) {
    var hexx = Number(str.charCodeAt(i)).toString(16);
    hex += (hexx.length > 1 && hexx || '0' + hexx);
  }
  return hex;
}
alert(a2hex('2460')); // display 32343630
SimonC
  • 365
  • 3
  • 11
0

I use this one, it seems more clear to me as I also receive data with spaces like '30 31 38 30 38 30' and the output is 018080

hexToString(hex: string): string {
   return hex.split(' ').map(s => string.fromCharCode(parseInt(s,16))).join('');
}