问一个编码转换问题,\x{6d4b}\x{8bd5}等于\x4b\x6d\xd5\x8b吗

问一个编码转换问题,\x{6d4b}\x{8bd5}等于\x4b\x6d\xd5\x8b吗

my $str="\x{6d4b}\x{8bd5}\x{4eba}\x{5458}", ##"测试人员"的utf-8编码
$encoded = encode_base64($str); ##我想把这个utf-8字串转换成base64,可是提示wide character in subroutine entry at ...程序退出
#可是如果我手工指定
my $str2 = "\x4b\x6d\xd5\x8b\xba\x4e\x58\x54";
$encoded = encode_base64($str2);就可以正常将utf-8编码的"测试人员"得到base64的编码:S23Vi7pOWFQ=


请问,"\x{6d4b}\x{8bd5}\x{4eba}\x{5458}"与"\x4b\x6d\xd5\x8b\xba\x4e\x58\x54"相同吗?
我该怎么将它们互相转换呢?谢谢
不用转换吧。 那个wild character ... 一般是在非unicode的环境下出现
你可以把环境set一下

PERL_UNICODE=S perl yourscript.pl 看看还有这个问题么?


仔细看了一下,base64只能转换single char

The string passed to encode_base64() contains characters with code above 255. The base64 encoding is only defined for single-byte characters. Use the Encode module to select the byte encoding you want.

一般来说出现
wild character只是warning不会导致程序推出吧


QUOTE:
原帖由 khandielas 于 2008-12-24 10:31 发表
不用转换吧。 那个wild character ... 一般是在非unicode的环境下出现
你可以把环境set一下

PERL_UNICODE=S perl yourscript.pl 看看还有这个问题么?


仔细看了一下,base64只能转换single char

Th ...

是这样的,这些wide charter(\x{6d4b}...)是通过前面语句XMLin得到的,
正如您所说,base64只能转换single char,所以我不能直接将wide char进行base64.
可是"测试人员"在utf-8文件的二进制码是\x4b\x6d\xd5\x8b\xba\x4e\x58\x54  (可以打开ultraedit,输入"测试人员",然后转换成utf-8格式,查看二进制ctrl+h)
对这些\x4b\x5d...进行base64,是可以正常得到信息的.

从字面上看,\x4b\x6d\xd5\x8b\xba\x4e\x58\x54  
           与 \x{6d4b}\x{8bd5}\x{4eba}\x{5458} 不是除了高低位不同,其他都差不多吗? 有什么办法可以转换呢?

我原是C程序员,转来写perl才学习几天,望各位大侠继续赐教

用代码来说明一下,
use Encode;
use MIME::Base64;
my $temp2 = "\x4b\x6d\xd5\x8b\xba\x4e\x58\x54";
print $encoded = encode_base64($temp2),"\n";  ##可以正常运行,得到S23Vi7pOWFQ=

my $temp3 = "\x{6d4b}\x{8bd5}\x{4eba}\x{5458}";   ##这些wide char通过前面的程序得来
print $encoded = encode_base64($temp3),"\n";  ##由于wide char缘故,程序退出.

可我只能得到这些wide char,该怎么把这些wide char转换成等价的singal char呢?

错,\x{6d4b}\x{8bd5}\x{4eba}\x{5458} 和 \x4b\x6d\xd5\x8b 完全是不同的东西。

首先澄清几个概念:
1. Perl中的字符串有两种存储方式:字节方式,宽字符方式(wide character)。
2. 宽字符方式每个字符占16位,是个0-65535的整数。
3. 宽字符的字符串不能被输出,也不能用作base64这样基于字节的字符串处理。
4. 为什么宽字符是16位?因为16位能完整地表示Unicode的所有字符。

你得到的 \x{6d4b}\x{8bd5}\x{4eba}\x{5458} 就是“测试人员”的宽字符形式。

5. 宽字符转换成字节要用 utf8::encode($str),反向转换用 utf8::decode($str)。
注意用这两个函数时不需要use utf8也不能use utf8,use utf8有别的意思,会产生重大影响!

6. \x{6d4b}\x{8bd5}\x{4eba}\x{5458}用 utf8::encode处理完后结果是
   \xe6\xb5\x8b\xe8\xaf\x95\xe4\xba\xba\xe5\x91\x98
   这才是应该传给 base64的数据。


QUOTE:
原帖由 odacharlee 于 2008-12-24 12:45 发表
错,\x{6d4b}\x{8bd5}\x{4eba}\x{5458} 和 \x4b\x6d\xd5\x8b 完全是不同的东西。

首先澄清几个概念:
1. Perl中的字符串有两种存储方式:字节方式,宽字符方式(wide character)。
2. 宽字符方式每个字符 ...

十分感谢您的帮助,如果要做一个邮件程序,肯定要转成您说说的utf-8格式.
但是我之所以要将\x{6d4b}\x{8bd5}\x{4eba}\x{5458} 变成 \x4b\x6d\xd5\x8b\xba\x4e\x58\x54 然后再进行base64是有原因的.
因为我有另外一个程序进行网络捕包,将网络包里\x4b\x6d\xd5\x8b这样的二进制流进行base64然后保存在数据库里等待查询
而这个程序是将一些关键词进行base64编码后到上面所说的数据库里进行查询,所以才有此问.

不过我在您的另一篇post中找到我的解决方案了,就是用ucs2-LE(utf-15LE)来encode即可,多谢多谢.
总结一下:
sub convert  
{
    my $in = shift;#$in=\x{6d4b}\x{8bd5}\x{4eba}\x{5458} 也就是"测试人员"
    my $out;
    my $temp = encode("ucs2",$in);    #utf-16
    #$temp = "mK嬚N篢X",反字节顺序   (拷入ultraedit,用二进制模式查看)
    my $temp = encode("ucs2-LE",$in); #utf-16LE
    #$temp = "Km諎篘XT" ,正是网络字节顺序 (拷入ultraedit,用二进制模式查看)
    my $temp = encode("gb2312",$in);
     #$temp = "测试人员". (拷入ultraedit,用二进制模式查看)
    my $temp = encode("utf-8",$in);
     #$temp = "娴嬭瘯浜哄憳". (拷入ultraedit,用二进制模式查看)

        print $encoded = encode_base64($temp),"\n";
}
这个帖子好,字符转换以后我也要用。 6楼解释的很清楚,谢谢。