我正在尝试将unicode字符串转换为javascript中的十六进制表示。
这就是我所拥有的:
function convertFromHex(hex) {
var hex = hex.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;
}
function convertToHex(str) {
var hex = '';
for(var i=0;i<str.length;i++) {
hex += ''+str.charCodeAt(i).toString(16);
}
return hex;
}
但是如果像中国人一样无法使用unicode角色;
输入: 汉字
输出: ªo“[W
有什么想法吗?这可以在javascript中完成吗?
答案 0 :(得分:81)
请记住,JavaScript代码单元是16位宽。因此,十六进制字符串形式将是每个代码单元4位数。
用法:
var str = "\u6f22\u5b57"; // "\u6f22\u5b57" === "漢字"
alert(str.hexEncode().hexDecode());
字符串到十六进制格式:
String.prototype.hexEncode = function(){
var hex, i;
var result = "";
for (i=0; i<this.length; i++) {
hex = this.charCodeAt(i).toString(16);
result += ("000"+hex).slice(-4);
}
return result
}
再次回来:
String.prototype.hexDecode = function(){
var j;
var hexes = this.match(/.{1,4}/g) || [];
var back = "";
for(j = 0; j<hexes.length; j++) {
back += String.fromCharCode(parseInt(hexes[j], 16));
}
return back;
}
答案 1 :(得分:9)
这取决于您使用的编码。如果要将utf-8编码的十六进制转换为字符串,请使用:
function fromHex(hex,str){
try{
str = decodeURIComponent(hex.replace(/(..)/g,'%$1'))
}
catch(e){
str = hex
console.log('invalid hex input: ' + hex)
}
return str
}
对于另一个方向,请使用:
function toHex(str,hex){
try{
hex = unescape(encodeURIComponent(str))
.split('').map(function(v){
return v.charCodeAt(0).toString(16)
}).join('')
}
catch(e){
hex = str
console.log('invalid text input: ' + str)
}
return hex
}
答案 2 :(得分:8)
如何从JavaScript
"\u6f22\u5b57"
获取漢字
?
这些是JavaScript Unicode escape sequences e.g. \u12AB
。要转换它们,您可以迭代字符串中的每个代码单元,在其上调用.toString(16)
,然后从那里开始。
但是,尽可能在输出中使用hexadecimal escape sequences e.g. \xAA
更有效。
另请注意,A
,b
和-
等ASCII符号可能不需要转义。
我已经编写了一个小型JavaScript库,可以为您完成所有这些工作,名为jsesc
。它有很多控制输出的选项。
以下是该工具的在线演示:http://mothereff.in/js-escapes#1%E6%BC%A2%E5%AD%97
您的问题被标记为utf-8
。阅读其余问题,UTF-8编码/解码似乎不是您想要的,但万一您需要它:use utf8.js
(online demo)。
答案 3 :(得分:8)
以下是McDowell算法的一个调整,它没有填补结果:
function toHex(str) {
var result = '';
for (var i=0; i<str.length; i++) {
result += str.charCodeAt(i).toString(16);
}
return result;
}
答案 4 :(得分:2)
这是我的观点:这些函数将UTF8字符串转换为适当的十六进制,而无需额外的零填充。实际的UTF8字符串包含长度为1、2、3和4个字节的字符。
在进行此工作时,我发现了一些可以解决我的问题的关键问题:
str.split('')
无法正确处理表情符号等多字节字符。解决这个问题的正确/现代方法是使用Array.from(str)
encodeURIComponent()
和decodeURIComponent()
是在字符串和十六进制之间转换的好工具。它们非常标准,可以正确处理UTF8。c.charCodeAt(0).toString(16)
非常适合那些人 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: function(hex) {
return decodeURIComponent('%' + hex.match(/.{1,2}/g).join('%'));
}
答案 5 :(得分:1)
一种最新的编码解决方案:
// This is the same for all of the below, and
// you probably won't need it except for debugging
// in most cases.
function bytesToHex(bytes) {
return Array.from(
bytes,
byte => byte.toString(16).padStart(2, "0")
).join("");
}
// You almost certainly want UTF-8, which is
// now natively supported:
function stringToUTF8Bytes(string) {
return new TextEncoder().encode(string);
}
// But you might want UTF-16 for some reason.
// .charCodeAt(index) will return the underlying
// UTF-16 code-units (not code-points!), so you
// just need to format them in whichever endian order you want.
function stringToUTF16Bytes(string, littleEndian) {
const bytes = new Uint8Array(string.length * 2);
// Using DataView is the only way to get a specific
// endianness.
const view = new DataView(bytes.buffer);
for (let i = 0; i != string.length; i++) {
view.setUint16(i, string.charCodeAt(i), littleEndian);
}
return bytes;
}
// And you might want UTF-32 in even weirder cases.
// Fortunately, iterating a string gives the code
// points, which are identical to the UTF-32 encoding,
// though you still have the endianess issue.
function stringToUTF32Bytes(string, littleEndian) {
const codepoints = Array.from(string, c => c.codePointAt(0));
const bytes = new Uint8Array(codepoints.length * 4);
// Using DataView is the only way to get a specific
// endianness.
const view = new DataView(bytes.buffer);
for (let i = 0; i != codepoints.length; i++) {
view.setUint32(i, codepoints[i], littleEndian);
}
return bytes;
}
示例:
bytesToHex(stringToUTF8Bytes("hello 漢字 ?"))
// "68656c6c6f20e6bca2e5ad9720f09f918d"
bytesToHex(stringToUTF16Bytes("hello 漢字 ?", false))
// "00680065006c006c006f00206f225b570020d83ddc4d"
bytesToHex(stringToUTF16Bytes("hello 漢字 ?", true))
// "680065006c006c006f002000226f575b20003dd84ddc"
bytesToHex(stringToUTF32Bytes("hello 漢字 ?", false))
// "00000068000000650000006c0000006c0000006f0000002000006f2200005b57000000200001f44d"
bytesToHex(stringToUTF32Bytes("hello 漢字 ?", true))
// "68000000650000006c0000006c0000006f00000020000000226f0000575b0000200000004df40100"
对于解码,通常要简单得多,您只需要:
function hexToBytes(hex) {
const bytes = new Uint8Array(hex.length / 2);
for (let i = 0; i !== bytes.length; i++) {
bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
}
return bytes;
}
然后使用TextDecoder
的编码参数:
// UTF-8 is default
new TextDecoder().decode(hexToBytes("68656c6c6f20e6bca2e5ad9720f09f918d"));
// but you can also use:
new TextDecoder("UTF-16LE").decode(hexToBytes("680065006c006c006f002000226f575b20003dd84ddc"))
new TextDecoder("UTF-16BE").decode(hexToBytes("00680065006c006c006f00206f225b570020d83ddc4d"));
// "hello 漢字 ?"
以下是允许的编码名称的列表:https://www.w3.org/TR/encoding/#names-and-labels
您可能会注意到UTF-32不在该列表中,这很痛苦,所以:
function bytesToStringUTF32(bytes, littleEndian) {
const view = new DataView(bytes.buffer);
const codepoints = new Uint32Array(view.byteLength / 4);
for (let i = 0; i !== codepoints.length; i++) {
codepoints[i] = view.getUint32(i * 4, littleEndian);
}
return String.fromCodePoint(...codepoints);
}
然后:
bytesToStringUTF32(hexToBytes("00000068000000650000006c0000006c0000006f0000002000006f2200005b57000000200001f44d"), false)
bytesToStringUTF32(hexToBytes("68000000650000006c0000006c0000006f00000020000000226f0000575b0000200000004df40100"), true)
// "hello 漢字 ?"
答案 6 :(得分:1)
您在这里。 :D
"漢字".split("").reduce((hex,c)=>hex+=c.charCodeAt(0).toString(16).padStart(4,"0"),"")
"6f225b57"
对于非unicode
"hi".split("").reduce((hex,c)=>hex+=c.charCodeAt(0).toString(16).padStart(2,"0"),"")
"6869"
ASCII(utf-8)二进制十六进制字符串到字符串
"68656c6c6f20776f726c6421".match(/.{1,2}/g).reduce((acc,char)=>acc+String.fromCharCode(parseInt(char, 16)),"")
字符串为ASCII(utf-8)二进制十六进制字符串
"hello world!".split("").reduce((hex,c)=>hex+=c.charCodeAt(0).toString(16).padStart(2,"0"),"")
--- Unicode ---
字符串为UNICODE(utf-16)二进制十六进制字符串
"hello world!".split("").reduce((hex,c)=>hex+=c.charCodeAt(0).toString(16).padStart(4,"0"),"")
UNICODE(utf-16)二进制十六进制字符串到字符串
"00680065006c006c006f00200077006f0072006c00640021".match(/.{1,4}/g).reduce((acc,char)=>acc+String.fromCharCode(parseInt(char, 16)),"")