为什么需要在 UTF-8 环境中“decode_utf8”LDAP 属性值?

问题描述 投票:0回答:1

我在 UTF-8 环境中编写了一个 Perl 程序(

LC_CTYPE="en_US.UTF-8"
,Emacs 显示“UUU”),它读取 UTF-8 编码的文件,插入从 OpenLDAP 服务器读取的一些属性值,然后将结果写入 UTF -8 编码文件。

看来我必须使用

use utf8;
use open IO => ':locale';
use open ':std' => ':locale';
use feature qw(unicode_strings);

除了

binmode $fh, ":utf8";
之外,再将输出写入
$fh

通过这些添加,Perl 中的字符串长度看起来是正确的,输出文件也是如此。

但是,正如我最近发现的那样,LDAP 中包含非 ASCII 字符(如德语变音符号)的属性值(某些

$ldap->search()
的结果)不正确。 因为它们在我看来就像“双重编码”,所以我像这样添加了解码(为条目创建哈希引用,由 DN 键入):

$data{$entry->dn} = {map {
    $_ => [map { decode_utf8($_) } $entry->get_value($_)]
} $entry->attributes(NLK_NO_OPTIONS => 1)};

工作时,这看起来很奇怪,我想知道是否有更优雅的解决方案(毕竟我不太明白内部发生了什么)。

为了测试,我创建了一个这样的用户:

dn: uid=testuser,ou=people,dc=company,dc=org
cn: User Test
gidNumber: 54321
givenName: User
homeDirectory: /tmp/testuser
loginShell: /bin/bash
sn: Test
uid: testuser
uidNumber: 54321
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
displayName:: QsO2c2VyIFVtbGF1dCBpbSBOYW1lbg==

如果没有修复,

displayName
将显示为“Böser Umlaut im Namen”,修复后它将显示为“Böser Umlaut im Namen”。

perl utf-8 openldap
1个回答
0
投票

您必须考虑所有数据边界。有时图书馆会为您做这件事,有时则不会。如果图书馆没有帮你做,你就必须自己做。

图书馆可能会对您隐藏这些详细信息,但在某些时候,某些东西必须了解有关输入的一些信息。您将获得八位字节。编码并没有什么神奇之处,它实际上只是关于解释八位组的指令。 当你交换数据时,你最终必须处理有线协议。

Perl 可以使用环境作为如何处理位的提示,但这并不意味着这些提示是正确的。您甚至可能有多个输入源,每个输入源都有不同的编码。

在始终为 UTF-8 的 JSON 世界中,所有这一切看起来都非常奇怪。这也让世界其他地方因为不一直使用 UTF-8 而显得非常愚蠢。但是,走到这一步也并不容易。

但是,我们使用的许多东西的历史都比 UTF-8 长得多;我认为 LDAP 和 UTF-8 大约是在同一时间开始的。后来出现的一些东西实现了 UTF-8 支持......奇怪的是(考虑如何让 MySQL 正确处理 UTF-8)。有些东西在 UTF-8 成为可能之前就实现了 Unicode 支持,而且它们无法立即改变。

我仍然遇到一些 UTF-16 的问题,这是一个完全不同的混乱,因为有不同的 UTF-16。回到我的科学职业生涯,我必须了解有关硬件的详细信息,以便知道如何处理磁带上的字节。我认为已经很长时间没有人关心大端或小端(甚至“网络”顺序)了。这些往往不是“大”或“小”;而是“大”或“小”。 Perl 的小端解包模板字母是 VAX 的“V”。

© www.soinside.com 2019 - 2024. All rights reserved.