17

i have my function to convert string to hex:

function encode(str){
    str = encodeURIComponent(str).split('%').join('');
    return str.toLowerCase();
}

example:

守护村子

alert(encode('守护村子'));

the output would be:

e5ae88e68aa4e69d91e5ad90

It works on Chinese characters. But when i do it with English letters

alert(encode('Hello World'));

it outputs:

hello20world

I have tried this for converting string to hex:

function String2Hex(tmp) {
    var str = '';
    for(var i = 0; i < tmp.length; i++) {
        str += tmp[i].charCodeAt(0).toString(16);
    }
    return str;
}

then tried it on the Chinese characters above, but it outputs the UTF-8 HEX:

5b8862a467515b50

not the ANSI Hex:

e5ae88e68aa4e69d91e5ad90

I also have searched converting UFT8 to ANSI but no luck. Anyone could help me? Thanks!

4
  • check out this answer. I think it might be what you're looking for.
    – nlloyd
    Commented Apr 15, 2016 at 2:17
  • Thanks but it is not the answer, it is similar to the String2Hex function above, that gives the utf8 hex code, not ansi hex code. But thanks anyway. Commented Apr 15, 2016 at 2:19
  • Try converting the text to latin1 using tmp = unescape(encodeURIComponent(str)) Commented Jul 6, 2017 at 5:42
  • 4
    Possible duplicate of Javascript: Unicode string to hex
    – Lukas Eder
    Commented Mar 6, 2018 at 13:33

6 Answers 6

26

As a self-contained solution in functional style, you can encode with:

plain.split("")
     .map(c => c.charCodeAt(0).toString(16).padStart(2, "0"))
     .join("");

The split on an empty string produces an array with one character (or rather, one UTF-16 codepoint) in each element. Then we can map each to a HEX string of the character code.

Then to decode:

hex.split(/(\w\w)/g)
   .filter(p => !!p)
   .map(c => String.fromCharCode(parseInt(c, 16)))
   .join("")

This time the regex passed to split captures groups of two characters, but this form of split will intersperse them with empty strings (the stuff "between" the captured groups, which is nothing!). So filter is used to remove the empty strings. Then map decodes each character.

3
  • 1
    @rumpel true! I’ve added a padStart. Commented Oct 11, 2020 at 23:09
  • 2
    This should be the accepted answer, since it works in modern browsers and node and does not require additional libraries.
    – Jankapunkt
    Commented Apr 6, 2021 at 14:37
  • Hmm... "fromCharCode" returns anything in between 0 and 65535, and to encode it properly you need 4 hex characters, not 2, right? Don't think this answer will work for any strings containing non-ASCII characters... Commented Jan 28, 2023 at 13:30
24

On Node.js, you can do:

const myString = "This is my string to be encoded/decoded";
const encoded = Buffer.from(myString).toString('hex'); // encoded == 54686973206973206d7920737472696e6720746f20626520656e636f6465642f6465636f646564
const decoded = Buffer.from(encoded, 'hex').toString(); // decoded == "This is my string to be encoded/decoded"
2
  • 15
    FYI: The Buffer class is not standardized by any standards body I know of, including ECMA. It is offered by Node.js, however, and does what you'd think it does. Commented Nov 17, 2018 at 13:23
  • 6
    Doesn't work in browsers. Not only isn't it standardized like amn says, but also it just doesn't exist, it's only a Node.js thing unfortunately. This means it doesn't answer the question because, obviously, alert() as OP used in the question doesn't make sense in Node.js, they clearly meant for this to work in a browser. But hopefully it still helps others that want to use this in server-side code...
    – Luc
    Commented Mar 19, 2021 at 13:10
2

I solved it by downloading utf8.js

https://github.com/mathiasbynens/utf8.js

then using the String2Hex function from above:

alert(String2Hex(utf8.encode('守护村子')));

It gives me the output I want:

e5ae88e68aa4e69d91e5ad90

3
2

This should work.

var str="some random string";
var result = "";
for (i=0; i<str.length; i++) {
    hex = str.charCodeAt(i).toString(16);
    result += ("000"+hex).slice(-4);
}
0
1

Another way to do it

function toHex(txt){
    const encoder = new TextEncoder();
    return Array
        .from(encoder.encode(txt))
        .map(b => b.toString(16).padStart(2, '0'))
        .join('')
}
1

If you want to properly handle UTF8 strings you can try these:

function utf8ToHex(str) {
  return Array.from(str).map(c => 
    c.charCodeAt(0) < 128
      ? c.charCodeAt(0).toString(16)
      : encodeURIComponent(c).replace(/\%/g,'').toLowerCase()
  ).join('');
}

function hexToUtf8(hex) {
  return decodeURIComponent('%' + hex.match(/.{1,2}/g).join('%'));
}

Demo: https://jsfiddle.net/lyquix/k2tjbrvq/

1
  • The utf8ToHex fails with the first character of the ascii table like new lines. It will produce "A" instead of "0A"
    – LatinSuD
    Commented Apr 10 at 19:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.