使用UTF8将Javascript十六进制转换为二进制

时间:2013-03-18 15:49:24

标签: php javascript character-encoding

我将SQLite数据库中的数据存储为BINARY(16),其值由PHP的{​​{3}}函数在32个字符的十六进制字符串上确定。

例如,字符串434e405b823445c09cb6c359fb1b7918会返回CN@[4EÀ¶ÃYûy

存储在此数据库中的数据需要由JavaScript操纵,为此,我使用了以下函数(改编自hex2bin的答案Andris):< / p>

// Convert hexadecimal to binary string
String.prototype.hex2bin = function ()
{

    // Define the variables
    var i = 0, l = this.length - 1, bytes = []

    // Iterate over the nibbles and convert to binary string
    for (i; i < l; i += 2)
    {
        bytes.push(parseInt(this.substr(i, 2), 16))
    }

    // Return the binary string
    return String.fromCharCode.apply(String, bytes)

}

这可以按预期工作,从CN@[4EÀ¶ÃYûy返回434e405b823445c09cb6c359fb1b7918

我遇到的问题是,当直接处理PHP的{​​{1}}函数返回的数据时,我会得到字符串hex2bin而不是CN@[�4E����Y�y 。这使得我无法在两者之间工作(对于上下文,CN@[4EÀ¶ÃYûy正被用于为使用从JavaScript网络应用程序检索的数据工作的离线iPad应用程序提供动力,因为我需要能够使用PHP生成32个字符的十六进制字符串,将其转换为二进制字符串,并使其与JavaScript的{​​{1}}函数(和PHP'一起使用s here功能)。

我认为,这个问题是hex2bin使用SQLite而二进制字符串存储为JavaScript。我最初的想法是,我需要将字符串转换为UTF-16。使用Google搜索引导我HEX并搜索StackOverflow,引导我here回答bobince,两者都建议使用utf8_unicode_ci。但是,这确实会返回我需要的内容(UTF-8):

unescape(encodeURIComponent(str))

我的问题是:

如何使用CN@[�4E����Y�y将十六进制字符串转换为// CN@[Â4EöÃYûy unescape(encodeURIComponent('434e405b823445c09cb6c359fb1b7918'.hex2bin())) 二进制字符串?

3 个答案:

答案 0 :(得分:2)

给定十六进制编码的UTF-8字符串,“hex”,

hex.replace(/../g, '%$&')

将生成URI编码的UTF-8字符串。

decodeURIComponent将URI编码的UTF-8序列转换为JavaScript UTF-16编码字符串,所以

decodeURIComponent(hex.replace(/../g, '%$&'))

应解码正确的十六进制编码的UTF-8字符串。

您可以通过将其应用于hex2bin文档中的示例来了解它的工作原理。

alert(decodeURIComponent('6578616d706c65206865782064617461'.replace(/../g, '%$&')));
// alerts "example hex data"

您提供的字符串不是UTF-8编码的。具体地,

434e405b823445c09cb6c359fb1b7918
        ^

82必须跟随一个至少设置了前两位的字节,并且5b不是这样一个字节。

RFC 2279解释说:

  

下表总结了这些不同八位字节类型的格式。   字母x表示可用于编码UCS-4的比特的比特   字符值。

UCS-4 range (hex.)           UTF-8 octet sequence (binary)
0000 0000-0000 007F   0xxxxxxx
0000 0080-0000 07FF   110xxxxx 10xxxxxx
0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx

答案 1 :(得分:1)

您的应用程序不必在任何时候处理二进制文件。插入是最新的可能点,这就是你的地方 最后转换为二进制。选择是最早可能的点,这是你转换为十六进制的地方,并使用 应用程序中的十六进制字符串。

插入时,可以用blob文字替换UNHEX

INSERT INTO table (id)
VALUES (X'434e405b823445c09cb6c359fb1b7918')

选择时,您可以HEX

SELECT HEX(id) FROM table

答案 2 :(得分:0)

扩展迈克的答案,这里有一些编码和解码的代码。

请注意,不推荐使用escape/unescape()函数。如果您需要填充,您可以查看更全面的UTF-8编码示例:http://jsfiddle.net/47zwb41o

// UTF-8 to hex
var utf8ToHex = function( s ){
    s = unescape( encodeURIComponent( s ) );
    var chr, i = 0, l = s.length, out = '';
    for( ; i < l; i++ ){
        chr = s.charCodeAt( i ).toString( 16 );
        out += ( chr.length % 2 == 0 ) ? chr : '0' + chr;
    }
    return out;
};

// Hex to UTF-8
var hexToUtf8 = function( s ){
    return decodeURIComponent( s.replace( /../g, '%$&' ) );
};