首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“子例程条目中的宽字符”- UTF-8编码的西里尔字作为字节序列

“子例程条目中的宽字符”- UTF-8编码的西里尔字作为字节序列
EN

Stack Overflow用户
提问于 2015-08-29 12:15:41
回答 4查看 14.2K关注 0票数 11

我在用一本大字典做一款安卓单词游戏-

单词(超过70万)保留为文本文件中的单独行(然后放入SQLite数据库)。

为了保护我的字典,我想用md5对超过3个字符的所有单词进行编码。(我不会用罕见的俄语字母ъэ混淆简短的单词和单词,因为我想在我的应用程序中列出它们)。

下面是我尝试在Mac上使用perl v5.18.2运行的脚本:

代码语言:javascript
复制
#!/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;
    
        if (length($_) <= 3 || /ъ/ || /э/) { # do not obfuscate short words
                print "$_\n";                # and words with rare letters
                next;
        }

        print md5_hex($_) . "\n";            # this line crashes
}

正如您所看到的,我必须在我的Perl脚本的源代码中使用西里尔字母--这就是为什么我将use utf8;放在它的顶部。

然而,我真正的问题是,length($_)报告的值太高(可能是字节数而不是字符数)。

所以我试着补充说:

代码语言:javascript
复制
binmode(STDOUT, ":raw");

或者:

代码语言:javascript
复制
binmode(STDOUT, ":utf8");

但是脚本会在子程序条目宽字符的print md5_hex($_)行中终止。

请帮我修一下我的剧本。

我把它作为:

代码语言:javascript
复制
perl ./generate-md5.pl < words.txt > encoded.txt

为了方便起见,下面是words.txt数据示例:

代码语言:javascript
复制
а
аб
абв
абвг
абвгд
съемка
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-08-29 12:44:32

md5_hex需要输入一个字节字符串,但是您要传递一个解码字符串( Unicode代码点的字符串)。显式编码字符串。

代码语言:javascript
复制
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";
票数 20
EN

Stack Overflow用户

发布于 2015-08-29 17:02:38

我真正的问题是长度($_)报告的值太高。

是的,您正在读取ARGV文件句柄,并且尚未将其编码设置为UTF-8。

您可以使用open杂注来修复这个问题。而不是所有的binmode语句,请使用

代码语言:javascript
复制
use open qw/ :std :encoding(utf8) /;

将所有文件句柄(包括标准文件句柄)的默认打开模式更改为:encoding(utf8)

票数 5
EN

Stack Overflow用户

发布于 2021-07-04 14:11:38

如果你使用to_json,那么将to_json替换为encode_json就可以解决这个问题。

从JSON模块的文档中,to_json关键字:如果您想要编写一个与外部世界通信的现代perl代码,您应该使用encode_json (假设JSON数据是用UTF-8编码的)。我不可能预见到一个非UTF-8世界。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32285925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档