首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将字符串的二进制数据与未知字符编码进行比较是否会验证其编码是什么?

将字符串的二进制数据与未知字符编码进行比较是否会验证其编码是什么?
EN

Stack Overflow用户
提问于 2021-11-19 15:17:06
回答 1查看 107关注 0票数 1

我需要自动确定字符编码的字符串从电子邮件内容和标题。在大多数情况下,这不是一个问题,但偶尔有一个电子邮件的内容和/或标题有一个古怪的字符,如一个恩达什。现在,我收到了一个答案,从技术上讲,如果我在一个特定的邮件头上静态地测试它,那么这个答案似乎是有效的,但是,这显然忽略了一个事实,即导入电子邮件必须是一个完全自动化的过程,在这种情况下,我完全无法自动确定字符串的字符编码。

我从一些基本知识开始,比如检测常见的故障字符,这些字符似乎保证了字符编码问题的发生。然而,strpos('en dash: –', '–')在有意/手动测试时运行良好,尽管它在直接添加到自动化过程时会彻底失败。我将猜测,问题是字符串参数具有UTF-8编码,而自动化过程正在测试一个尚未UTF-8的字符串,因此内部相同的字符没有使用相同的代码子集(通过字符编码)。

因此,我的第二次尝试是编码的第二个参数可以是一个数组。

代码语言:javascript
复制
$encodings = array('UTF-8','UCS-4','UCS-4BE','UCS-4LE','UCS-2','UCS-2BE','UCS-2LE','UTF-32','UTF-32BE','UTF-32LE','UTF-16','UTF-16BE','UTF-16LE','UTF-7','UTF7-IMAP','ASCII','EUC-JP','SJIS','eucJP-win','SJIS-win','ISO-2022-JP','ISO-2022-JP-MS','CP932','CP51932','SJIS-mac','SJIS-Mobile#DOCOMO','SJIS-Mobile#KDDI','SJIS-Mobile#SOFTBANK','UTF-8-Mobile#DOCOMO','UTF-8-Mobile#KDDI-A','UTF-8-Mobile#KDDI-B','UTF-8-Mobile#SOFTBANK','ISO-2022-JP-MOBILE#KDDI','JIS','JIS-ms','CP50220','CP50220raw','CP50221','CP50222','ISO-8859-1','ISO-8859-2','ISO-8859-3','ISO-8859-4','ISO-8859-5','ISO-8859-6','ISO-8859-7','ISO-8859-8','ISO-8859-9','ISO-8859-10','ISO-8859-13','ISO-8859-14','ISO-8859-15','ISO-8859-16','byte2be','byte2le','byte4be','byte4le','BASE64','HTML-ENTITIES','7bit','8bit','EUC-CN','CP936','GB18030','HZ','EUC-TW','CP950','BIG-5','EUC-KR','UHC','ISO-2022-KR','Windows-1251','Windows-1252','CP866','KOI8-R','KOI8-U','ArmSCII-8');
$encoding = mb_detect_encoding($s, $encodings, true);
$compare = mb_convert_encoding($s, 'UTF-8', $encoding);

foreach ($encodings as $k1)
{
 if (mb_convert_encoding($s, 'UTF-8', $k1) === $s) {$encoding = $k1; break;}
}

不幸的是,基于我认为同样的根本问题,这似乎导致了同样的失败。

因此,我的第三个想法,我正在寻找一些更有经验的验证。我可以将字符串转换成二进制形式(1和0,而不是二进制数据)。然后,我可以尝试转换字符串,然后将第二个字符串转换为二进制,以比较这两个二进制版本;如果它们===匹配,那么我可能已经确定了正确的字符编码?

现在,我可以很容易地从一个不相关的线程尝试这个有了这个答案,但是我不确定这是否是一个有效的想法。这一切都是为了回答我的问题:

如何确定字符串的实际字符编码,以便在不损坏数据的情况下将其转换为具有完全自动化验证的UTF-8?

通过验证,我说的是一些东西,比如比较二进制数据,但我不确定这是否有效。我知道我非常讨厌破折号。

EN

回答 1

Stack Overflow用户

发布于 2021-11-25 11:53:44

答案不会改变:这是不可能的。您必须依赖于文本上使用的外部信息进行编码。

猜测编码可能会出现可怕的错误:

  • 根据您对其进行测试的顺序,可以选择ASCIIUTF-8Windows-1252,因为到目前为止,它是符合的。您的列表是有问题的,因为它可能与Base64匹配,这甚至不是文本编码。
  • 如果源本身没有正确编码,那么猜测它的编码很可能会排除正确的编码。猜错了。这会让事情更糟。
  • 许多编码都有相同的地方:源既可以是Windows-1252,也可以是Windows-1251,甚至检测到文本的词义也不能保证两者都是正确的。

还有:1和0是二进制的。PHP字符串只是字节数组。,所以它们一开始是二进制的。如何解释它们取决于您:如果您的代码是$text= "グリーン";,那么就取决于您的PHP文本文件的编码方式以及如何设置PHP默认值。没有“内部.字符”,只有字节。这也是为什么存在在字节(即strlen())和特定文本编码(即mb_strlen())上操作的函数。

如果你讨厌单个字符,那么它们可以很容易地用作文本中的字符。----相比,有它自己的有效意义;不要用个人观点来代替它,因为这可能会破坏上下文的意义。这就像忽略了这样一个事实:一个Α以及一个都是不同的字符。您可能需要查找_homo_glyphs和_syno_glyphs之间的区别-后者是您当前的透视图。

您可能会问:“PHP在哪种编码中解释脚本?”幸运的是,对于大多数编码来说,ASCII是最常见的分母,因此将文件的第一个字节解释为搜索<?php (所有这些都是ASCII字符,所以对于PHP代码本身来说,它实际上是UTF-8还是ISO-8859-1或< code >E 142Shift-JISE 243)只有在文档被编码时才会失败,即E 144UTF-16e 245/code>-在这种情况下,您必须将您的PHP默认值设置为该编码。这再次证明:文本编码必须在文本之外被告知。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70037066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档