Ale*_*ber 7 unicode perl md5 utf-8 cyrillic
我正在开发一个带有大字典的Android文字游戏 -
单词(超过700 000)在文本文件中保存为单独的行(然后放入SQLite数据库中).
为了防止竞争对手提取我的字典,我想用md5编码长度超过3个字符的所有单词.(我不混淆简单的字和词与难得的俄文字母?和?,因为我想将它们列在我的应用程序).
所以这是我尝试在Mac Yosemite上使用perl v5.18.2运行的脚本:
#!/usr/bin/perl -w
use strict;
use utf8;
use Digest::MD5 qw(md5_hex);
binmode(STDIN, ":utf8");
#binmode(STDOUT, ":raw");
binmode(STDOUT, ":utf8");
while(<>) {
chomp;
next if length($_) < 2; # ignore 1 letter junk
next if /??/; # impossible combination in Russian
next if /??/; # impossible combination in Russian
s/?/?/g;
#print "ORIGINAL WORD $_\tENCODED WORD: ";
if (length($_) <= 3 || /?/ || /?/) { # do not obfuscate short words
print "$_\n"; # and words with rare letters
next;
}
print md5_hex($_) . "\n"; # this line crashes
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我必须在我的Perl脚本的源代码中使用西里尔字母 - 这就是为什么我把use utf8;它放在顶部.
但是我真正的问题是length($_)报告的值太高(可能是报告字节数而不是字符数).
所以我尝试添加:
binmode(STDOUT, ":raw");
Run Code Online (Sandbox Code Playgroud)
要么:
binmode(STDOUT, ":utf8");
Run Code Online (Sandbox Code Playgroud)
但是脚本随后在子行程序条目中以宽字符死亡print md5_hex($_).
请帮我修改我的脚本.
我把它当作:
perl ./generate-md5.pl < words.txt > encoded.txt
Run Code Online (Sandbox Code Playgroud)
这里是示例words.txt数据为方便起见:
?
??
???
????
?????
??????
Run Code Online (Sandbox Code Playgroud)
AnF*_*nFi 15
md5_hex期望输入的字节串,但是您传递的是已解码的字符串(Unicode代码点字符串).显式编码字符串.
use strict;
use utf8;
use Digest::MD5;
use Encode;
# ....
# $_ is assumed to be utf8 encoded without check
print Digest::MD5::md5_hex(Encode::encode_utf8($_)),"\n";
# Conversion only when required:
print Digest::MD5::md5_hex(utf8::is_utf8($_) ? Encode::encode_utf8($_) : $_),"\n";
Run Code Online (Sandbox Code Playgroud)
我真正的问题是 length($_) 报告的值太高
是的,您正在读取ARGV文件句柄,但尚未将其编码设置为 UTF-8
您可以使用open编译指示来解决此问题。而不是你所有的binmode陈述,使用
use open qw/ :std :encoding(utf8) /;
Run Code Online (Sandbox Code Playgroud)
这会将所有文件句柄(包括标准文件句柄)的默认打开模式更改为 :encoding(utf8)
| 归档时间: |
|
| 查看次数: |
9468 次 |
| 最近记录: |