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

Php 使用UTF8将Javascript十六进制转换为二进制,php,javascript,character-encoding,Php,Javascript,Character Encoding,我将数据存储在SQLite数据库中,作为BINARY(16),其值由PHP函数在32个字符的十六进制字符串上确定 例如,字符串434e405b823445c09cb6c359fb1b7918返回CN@[4EÀÀYúY 存储在此数据库中的数据需要由JavaScript操作,为此,我使用了以下函数(改编自的答案): 那么,我的问题是: 如何使用JavaScript将十六进制字符串转换为UTF-8二进制字符串?给定十六进制编码的UTF-8字符串,`hex' hex.replace(/../g, '%$

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

例如,字符串
434e405b823445c09cb6c359fb1b7918
返回
CN@[4EÀÀYúY

存储在此数据库中的数据需要由
JavaScript
操作,为此,我使用了以下函数(改编自的答案):

那么,我的问题是:


如何使用
JavaScript
将十六进制字符串转换为
UTF-8
二进制字符串?

给定十六进制编码的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不是这样的字节

说明:

下表总结了这些不同八位组类型的格式。 字母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

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

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

INSERT INTO table (id)
VALUES (X'434e405b823445c09cb6c359fb1b7918')
选择时,您可以
HEX

SELECT HEX(id) FROM table

下面是一些编码和解码的代码

请注意,
escape/unescape()
函数已被弃用。如果您需要多填充,可以查看此处更全面的UTF-8编码示例:

//UTF-8到十六进制
var utf8ToHex=函数{
s=unescape(一个或多个组件);
变量chr,i=0,l=s.length,out='';
对于(;i
“当直接处理PHP的
hex2bin
函数返回的数据时,我得到了字符串
CN@[�4E����Y�y
而不是
CN@[4EÀÀyÿy
”-这听起来更像是一个编码问题。如何将数据从PHP传递到JS?它是从SQLite数据库中提取出来的。如果数据表示字符,为什么是
二进制(16)
?如果数据不表示字符,为什么要将其转换为字符?我将UUID存储为
二进制(16)
在数据库中。这需要由
PHP
JavaScript
生成、检索和使用。我正在使用
SQLite
HEX
函数在选择
UUID
时获取十六进制字符串。问题是在使用
HEX(UUID)时
在由上面的
hex2bin
JavaScript
函数生成的UUID上,它与生成的实际十六进制字符串不同(而
PHP
hex2bin
函数工作正常)@MichaelRushton,但它支持blob文本。因此,您只需要在引用的十六进制字符串前面添加
X
。将
UNHEX('434e405b823445c09cb6c359fb1b7918')
替换为
X'434e405b823445c09c359fb1b7918'
问题在于生成UTF-8字节字符串(在
JavaScript
中),而不是检索它(来自
PHP
/
SQLite
)。如果不清楚,很抱歉。@MichaelRushton,我仍然不清楚。给定一个常规的(UTF-16编码的)JS字符串,您想获取十六进制编码字符串,还是获取UTF-8八位字符串?我需要将十六进制字符串存储为
BINARY
。此二进制字符串需要由
PHP
JavaScript
生成。问题是
PHP
hexin
函数返回的二进制字符串与o上面的自定义
JavaScript
hex2bin
函数返回的二进制字符串,尽管十六进制字符串是相同的。我知道
JavaScript
函数是正确的,因为它返回的可视字符与数据库中的相同——只是当从数据库中拉出浏览器时ows不同的字符(可能是不同的编码).@MichaelRushton,请看我的重写。十六进制字符串是由这个答案中的代码生成的:完美的+1,并被接受。它可能无法按照文字回答问题,但它确实按照解释解决了问题。@MichaelRushton解释PHP“字符串”之间的区别并不是一个小任务还有其他语言(如Javascript)中的字符串,所以我很高兴避免了它:后续问题:这能与准备好的语句一起工作吗?我尝试了
(x?
,但结果是错误(正如我一半预期的那样)。还尝试了连接
(x | |?)
这也不行。@MichaelRushton您必须将其直接连接到查询中,PDO或mysqli似乎不支持在预处理语句绑定中直接使用二进制数据。
INSERT INTO table (id)
VALUES (X'434e405b823445c09cb6c359fb1b7918')
SELECT HEX(id) FROM table
// 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, '%$&' ) );
};