【问题标题】:MD5 conversion of unicode textUnicode文本的MD5转换
【发布时间】:2013-07-20 04:27:33
【问题描述】:

我制作了一本包含大约 10 万个 Unicode 旁遮普语单词的字典。有一个字母,它的unicode代码是ਸ਼,还有很多这样的字母。但是在这种语言中,字母下面的点也可以单独输入,但unicode中有组合字母。在数据库中,word 表中有单词,word_hash 中有单词的 md5。当我尝试使用带有语句SELECT * FROM db WHERE word_hash = md5('word'); 的php 搜索数据库时,它会导致找不到带有带有点的此类字母的单词的记录。当我尝试搜索时,我发现db中单词的md5和搜索语法生成的md5不同。为什么会这样?我已经通过文本框输入了所有单词,输入的 md5 是 mysql 语法。

例如:单词ਸ਼ਰਬਤ 的代码是由mysql 查询回显的45f756f02a28b5ec48ddf369db6ad7e6,在数据库中是d6da1a44526c5ab1259dcc05404b1e8c

的两个替代品是 ਸ਼ਸ਼

【问题讨论】:

  • 为什么用哈希而不是单词搜索?您应该将单词存储在normalized form 中。然后您可以使用单词而不是哈希进行搜索。
  • 我需要使用 md5 进行搜索,因为当我以标准化形式进行搜索时,它认为带点和不带点的字母相同..所以如果有一个没有点的单词,它会显示结果即使我们输入点...

标签: php mysql unicode


【解决方案1】:

这里有不同的 Unicode 规范化形式。有组合字符,其中一个基本字符与一个变音符号或其他字符组合形成一个替代版本,但有时这个替代版本也可能作为独立字符存在。例如:

ਸ਼ GURMUKHI LETTER SHA (U+0A36)
ਸ GURMUKHI LETTER SA  (U+0A38)
 ਼ GURMUKHI SIGN NUKTA (U+0A3C)
ਸ +  ਼ (U+0A38 + U+0A3C) equivalent to ਸ਼ U+0A36

(我实际上不确定 GURMUKHI SIGN NUKTA 是否是正确的组合点,因为我不知道 Gurmukhi,但你明白了。)

对于存储和比较,您应该选择一种形式或另一种形式,因为通常无法预测输入将采用哪种格式。您可以使用 Unicode 规范化过程来执行此操作,该过程在两种形式之间进行转换。在 PHP 中,您可以使用 Normalizer class

我需要使用 md5 进行搜索,因为当我以标准化形式进行搜索时,它认为带点和不带点的字母相同..

您的第二个问题是您正在为一个简单的问题发明一个过于复杂的解决方案:排序规则。数据库使用排序规则进行“模糊”匹配,即将“matinee”和“matineé”视为相同,或者在您的情况下为“ਸ਼”和“ਸ”。你在列上设置了默认排序规则,但是你can influence it during query time as well

SELECT ... WHERE foo = 'bar' COLLATE utf8_bin;

如果您想要绝对匹配,请使用 utf8_bin 排序规则或其他等效的 _bin(二进制)排序规则来选择编码。

【讨论】:

  • 我要补充一点,即使在标准化为 NFC 时,U+0A36 也会变为 U+0A38 + U+0A3C,因为该字符被列为 composition exclusion。这可能解释了“认为带有和不带有点的字母相同”的评论,尽管我不确定。
  • thxx fr ur answer...但是当我将编码更改为 utf8_bin 时...它甚至不显示一条记录...
  • @sha Collat​​ion! 编码是utf8,但你担心的是collat​​ion utf8_bin。无论如何,如果它不匹配,那是因为二进制 (_bin) 值不同。您是否将搜索值和数据库中的值都标准化为与上述相同的标准化形式?
  • 我无法使用normalizer 类....我已经在 wampserver 中启用了php_intl 扩展...但normalizer_normalise() 仍然无法正常工作...跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-19
  • 1970-01-01
  • 2019-06-07
相关资源
最近更新 更多