Mysql HEX函数解码多字节utf8

时间:2012-07-15 04:31:55

标签: php mysql utf-8 character-encoding mysqli

MySQL使用函数HEX()将一系列字符转换为十六进制表示。唯一的问题是它假设每个字符都是两个字节。这对大多数情况都很好,但是对于utf-8,有时字符跨度超过2个字节。

例如。 0xEFBFBD是用于表示编码错误的三字节字符。当我在DB中一个接一个地使用这两个字符时(总共6个字节),在utf8编码表中,我尝试SELECT HEX(col1)FROM table ...,这就是0xC3AFC2BFC2BD而不是0xEFBFBD。如果我在php中使用查询选择它,然后在php中转换为十六进制,它将以正确的格式显示。

最好的是一个函数是MySql,它可以解码正确的多字节UTF8。我很惊讶它似乎不存在,并且想知道是否还有其他人发现了这种情况并且可能的解决方案。

我在MySql中找到的答案最接近的是: http://forums.mysql.com/read.php?103,375304,375660

但这个建议并没有真正帮助。如果没有人有任何想法,我会稍后发布一个测试用例。

1 个答案:

答案 0 :(得分:2)

HEX函数返回实际存储的字节数;记住,MySQL很乐意存储一系列字符编码。如果为每个字符获得两个字节,则必须在ucs2 or utf16中编码您的值。要检查编码,您可以使用CHARSET function

在这种特殊情况下,该列包含以UTF-16编码的쎯쎯(U + C3AF U + C2BF U + C2BD)。必须有一些其他问题让你相信 (U + FFFD U + FFFD)是储值。也许您的PHP程序使用ucs2utf16作为连接字符集,然后将获得的文本视为UTF-8?


更新:要获取字符串的UTF-8编码的十六进制表示形式 - 任何编码*中的任何字符串 - ),请使用HEX(CONVERT(string USING utf8))。例如:

set @unknown = char(0xFFFD using ucs2);        -- stored bytes: \xFF \xFD
select hex(convert(@unknown using utf8));      -- output: EFBFBD

*)除了没有要转换的编码的二进制字符串