2

我有一堆以人名命名的文件(例如“john.txt”、“mary.txt”),但其中也有日文名称(例如“fūka.txt”、“tetsurō.txt”)。

我要做的是将“.txt”之前的名称转换为Base64。

唯一的问题是,当我使用文件名(不带扩展名)并使用基于 Web 的转换器时,我得到的结果与借助 Python 脚本进行编码不同。

所以......例如,当我复制没有扩展名的文件名部分并在http://www.base64encode.org中编码“fūka”时,我得到“ZsWra2E =”。当我从 UTF-8 编码的 PostgreSQL 数据库中获取人名时,我得到的结果相同,将其设为小写并进行 base64 编码。

但是当我在下面使用 Python 脚本时,我得到“ZnXMhGth”

import glob, os
import base64

def rename(dir, pattern):
    for pathAndFilename in glob.iglob(os.path.join(dir, pattern)):

        title, ext = os.path.splitext(os.path.basename(pathAndFilename))

        t = title.lower().encode("utf-8")

        encoded_string = base64.b64encode(t) + ext

        p = os.path.join(dir, encoded_string)

        os.rename(pathAndFilename, p)

rename(u'./test', u'*.txt')

我在 OS X 10.8 和 Linux(从 Mac 上传到 Linux 服务器的文件)中得到了相同的结果。Python 是 2.7。我也尝试了 PHP 脚本(结果与 Python 脚本相同)。

当我使用带有其他字符的名称(例如“tetsurō”)时,也会发生类似的差异。

更奇怪的事情......当我在 OS X 的终端应用程序中使用 Python 脚本输出文件名部分,然后将此文本复制为文件名......然后将文件名编码为 base64 时,我得到的结果与我在网页上的结果相同上文提到的。终端具有 UTF-8 编码。

有人可以解释一下我在做什么(或在想)错了吗?中间是否有一些小的字符替换正在进行?如何使 Python 脚本获得与上述网页相同的结果任何提示将不胜感激。

解决方案:

在 Marks 回答的帮助下,我修改了一个脚本,它就像一个魅力!谢谢马克!

import glob, os
import base64
from unicodedata import normalize

def rename(dir, pattern):
    for pathAndFilename in glob.iglob(os.path.join(dir, pattern)):

        title, ext = os.path.splitext(os.path.basename(pathAndFilename))

        t = normalize('NFC', title.lower()).encode("utf-8") # <-- NORMALIZE !!!

        encoded_string = base64.b64encode(t) + ext

        p = os.path.join(dir, encoded_string)

        os.rename(pathAndFilename, p)

rename(u'./test', u'*.txt')
4

1 回答 1

0

看来 Python 脚本使用的是规范化形式的 Unicode,其中ū已被分成两个字符u和一个组合宏另一种形式使用带有 macron的单字符拉丁小写字母u。就 Unicode 而言,它们是相同的字符串,即使它们没有相同的二进制表示。

您可能会从这个 Unicode 常见问题解答中获得更多信息:http ://www.unicode.org/faq/normalization.html

于 2013-02-22T16:22:06.223 回答