Skip to main content
 首页 » 编程设计

python之使用日语字符时,在 OS X 上将文件名编码为 base64 不正确

2025年05月04日14davidwang456

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

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

唯一的问题是,当我使用一个文件名(没有扩展名)并使用基于网络的转换器时,我得到的结果与借助我的 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 answer 的帮助下,我修改了一个脚本,效果非常好!谢谢马克!

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') 

请您参考如下方法:

看来 Python 脚本使用的是标准化形式的 Unicode,其中 ū 已拆分为两个字符,u 和 combining macron .另一种形式使用单个字符 latin small letter u with macron .就 Unicode 而言,它们是相同的字符串,即使它们没有相同的二进制表示。

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