我有一堆以人名命名的文件(例如“john.txt”,“mary.txt”),但其中也有日文名称(例如“fūka.txt”,“tetsurō.txt”)。 / p>
我要做的是将“.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时,我得到的结果与on相同我上面提到的网页。终端具有UTF-8编码。
有人可以解释一下我在做什么(或思考)错了吗?是否有某些小字符替换正在进行中?如何使Python脚本获得与上述网页相同的结果任何提示将不胜感激。
SOLUTION:
在Marks回答的帮助下,我修改了一个脚本,它就像一个魅力!谢谢Mark!
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')
答案 0 :(得分:0)
似乎Python脚本使用的是规范化形式的Unicode,其中ū
已分为两个字符u
和combining macron。另一种形式使用单个字符latin small letter u
with macron。就Unicode而言,即使它们没有相同的二进制表示,它们也是相同的字符串。
您可以从此Unicode常见问题解答中获取更多信息:http://www.unicode.org/faq/normalization.html