了解有关编码 U+30C9 与 U+30C8U+3099 的更多信息
To Understand More about Encoding U+30C9 vs U+30C8U+3099
ド(U+30C9) vs ド(U+30C8U+3099)
顺便说一句,情况是
- 用户从网络应用程序上传了名称包含
ド(U+30C8U+3099)
的文件到 AWS s3。
- 然后,该网站向 AWS lambda 函数发送了一个 POST 请求,其中包含没有 url 编码的文件名,以便使用 Python 进行进一步处理。到达Lambda时的名字变成了
ド(U+30C9)
。 Python 然后由于unicode的不同,无法访问存储在s3中的文件。
我认为解决方案是在发送请求之前在前端进行 url 编码,然后使用 urllib.parse.unquote
进行 url 解码以获得相同的 unicode。
我的问题是
url编码能解决那个问题吗?我无法重现相同的问题,可能是因为我与用户的 OS.
处于不同的 OS
这两个请求(上传到 s3 并将第二个请求发送到 lambda)都发生在用户的机器上,究竟是如何发生的?
谢谢。
您遇到了一个常见情况(在拉丁文字中可能更常见):规范对等。 Unicode 要求以相同的方式处理规范的等效序列。
如果您查看 UnicodeData.txt,您会发现:
30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;;
30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;;
所以,30C9 等价于 30C8 3099。
通常,最好将 Unicode 字符串规范化为常见的规范形式。不幸的是,我们有两个:NFC 和 NFD:归一化形式规范组合和规范化形式规范分解。 Apple 更喜欢后者(而 Unicode 原始 design/preference 是关于这种形式的),而大多数其他供应商都是第一种。
所以不要相信网络浏览器会保持相同的形式。但也要考虑到用户端的输入法可能会给您带来不同的变化(并且对于键盘,您可能还有 non-canonical 应该规范化的形式 [这可能发生在多个组合字符中])。
所以,在你的后端你应该选择一个规范化形式,并以这种形式转换所有输入数据(或者只是确保所有搜索和比较函数都能正确处理等效序列,但这需要在每次调用时进行规范化,所以它可能效率较低)。
Python 有 unicodedata.normalize()
(在标准库中,参见 unicodedata module),以标准化 Unicode 字符串。最终在其他语言上你应该使用 ICU 库。无论如何,您应该规范化 Unicode 字符串。
注意:这与编码无关,但它直接内置于 Unicode 设计中。原因是要求与旧编码兼容,而旧编码有两种方式来描述相同的字符。
ド(U+30C9) vs ド(U+30C8U+3099)
顺便说一句,情况是
- 用户从网络应用程序上传了名称包含
ド(U+30C8U+3099)
的文件到 AWS s3。 - 然后,该网站向 AWS lambda 函数发送了一个 POST 请求,其中包含没有 url 编码的文件名,以便使用 Python 进行进一步处理。到达Lambda时的名字变成了
ド(U+30C9)
。 Python 然后由于unicode的不同,无法访问存储在s3中的文件。
我认为解决方案是在发送请求之前在前端进行 url 编码,然后使用 urllib.parse.unquote
进行 url 解码以获得相同的 unicode。
我的问题是
url编码能解决那个问题吗?我无法重现相同的问题,可能是因为我与用户的 OS.
处于不同的 OS这两个请求(上传到 s3 并将第二个请求发送到 lambda)都发生在用户的机器上,究竟是如何发生的?
谢谢。
您遇到了一个常见情况(在拉丁文字中可能更常见):规范对等。 Unicode 要求以相同的方式处理规范的等效序列。
如果您查看 UnicodeData.txt,您会发现:
30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;;
30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;;
所以,30C9 等价于 30C8 3099。
通常,最好将 Unicode 字符串规范化为常见的规范形式。不幸的是,我们有两个:NFC 和 NFD:归一化形式规范组合和规范化形式规范分解。 Apple 更喜欢后者(而 Unicode 原始 design/preference 是关于这种形式的),而大多数其他供应商都是第一种。
所以不要相信网络浏览器会保持相同的形式。但也要考虑到用户端的输入法可能会给您带来不同的变化(并且对于键盘,您可能还有 non-canonical 应该规范化的形式 [这可能发生在多个组合字符中])。
所以,在你的后端你应该选择一个规范化形式,并以这种形式转换所有输入数据(或者只是确保所有搜索和比较函数都能正确处理等效序列,但这需要在每次调用时进行规范化,所以它可能效率较低)。
Python 有 unicodedata.normalize()
(在标准库中,参见 unicodedata module),以标准化 Unicode 字符串。最终在其他语言上你应该使用 ICU 库。无论如何,您应该规范化 Unicode 字符串。
注意:这与编码无关,但它直接内置于 Unicode 设计中。原因是要求与旧编码兼容,而旧编码有两种方式来描述相同的字符。