【问题标题】:utf8 on in dancer but not scriptutf8 在 dancer 但不是脚本
【发布时间】:2012-03-20 02:53:44
【问题描述】:

这是对my previous question on showing unicode string differences 的跟进。事实证明,这些字符串看起来是一样的,但是其中一个字符串的 UTF8 标志是打开的。

SV = PVMG(0x4cca750) at 0x4b3fc90
 REFCNT = 1
 FLAGS = (PADMY,POK,pPOK,UTF8)
 IV = 0
 NV = 0
 PV = 0x1eda410 "flurbe"\0 [UTF8 "flurbe"]
 CUR = 6
 LEN = 16

SV = PV(0xf28090) at 0xf4b6a0
 REFCNT = 1
 FLAGS = (PADMY,POK,pPOK)
 PV = 0xf37b90 "flurbe"\0
 CUR = 6
 LEN = 16

当我加密字符串时,这似乎会对生成的 sha512 哈希值产生影响。据我所知,Dancer 是导致第一个结果具有 utf8 的原因,我的另一个脚本只是一个命令行脚本,没有使用 dancer,我怎么能强制它以相同的方式运行?

【问题讨论】:

  • 字符串的 utf8 状态不应影响其 SHA512 哈希值。无论哪种方式都应该是1cd2e...6bdf1。你得到什么哈希值?
  • 明天我得去看看工作,但不管怎样,它们都不一样。这是我能够找到的唯一区别,当然它可能是在某处启用的其他一些 utf8 东西。我的哈希也是随机加盐的......
  • @xenoterracide:你的随机盐是什么样的?如果它们是非 UTF-8 升级的字符串,并且它们包含\x00-\x7F 范围之外的字节,那么在与 UTF-8 升级的字符串连接后它们看起来会有所不同。
  • 老实说,我想它甚至可能是盐或其他东西,但我非常有信心启用 utf8 是不同的。
  • @xenoterracide:我已经更新了我的“答案”以澄清我的意思。我并不是说盐是问题。相反,我是说盐可能是导致 UTF-8 升级成为问题的原因。

标签: perl unicode dancer


【解决方案1】:

(这更像是一个评论而不是一个答案,但它太大了。)

我刚刚运行了这个程序:

#!/usr/bin/perl -w

use warnings;
use strict;

use Devel::Peek ();
use Digest::SHA ();

my $x = 'flurbe';

Devel::Peek::Dump $x;

print Digest::SHA::sha512_hex($x), "\n\n";

utf8::upgrade $x;

Devel::Peek::Dump $x;

print Digest::SHA::sha512_hex($x), "\n";

__END__

它给出了这个输出:

SV = PV(0x10441040) at 0x10491638
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x10449ca0 "flurbe"\0
  CUR = 6
  LEN = 8
1cd2e71e55653caeb6c9bffa47a66ff1c9b526bbb732dcff28412090601e9b5e34d36be6a0267527347cd94039b383d4bc45653d786d1041debe7faa0716bdf1

SV = PV(0x10441040) at 0x10491638
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK,UTF8)
  PV = 0x10449ca0 "flurbe"\0 [UTF8 "flurbe"]
  CUR = 6
  LEN = 8
1cd2e71e55653caeb6c9bffa47a66ff1c9b526bbb732dcff28412090601e9b5e34d36be6a0267527347cd94039b383d4bc45653d786d1041debe7faa0716bdf1

如您所见,Devel::Peek::Dump 正确识别字符串已升级为 UTF-8,但这不会影响由Digest::SHA 计算的 SHA-512 哈希。

编辑添加:在上面的评论中,您提到您的“哈希是随机加盐的”。这些盐可以包含 ASCII 范围之外的字节吗?如果是这样,与 UTF-8 升级的字符串连接会影响其内容。我刚刚运行了这个修改后的程序:

#!/usr/bin/perl -w

use warnings;
use strict;

use Devel::Peek ();
use Digest::SHA ();

my $x = 'flurbe';
my $y = "\xA0";      # a single byte, hex 00A0
my $z = "\xC2\xA0";  # UTF-8 representation of U+00A0, as a byte-string

Devel::Peek::Dump "$x$y";
print Digest::SHA::sha512_hex("$x$y"), "\n\n";

Devel::Peek::Dump "$x$z";
print Digest::SHA::sha512_hex("$x$z"), "\n\n";

utf8::upgrade $x;

Devel::Peek::Dump "$x$y";

print Digest::SHA::sha512_hex("$x$y"), "\n";

__END__

它给出了这个输出:

SV = PV(0x104410e8) at 0x104d68d8
  REFCNT = 1
  FLAGS = (PADTMP,POK,pPOK)
  PV = 0x10449ca0 "flurbe\240"\0
  CUR = 7
  LEN = 8
1901f989ed76143697ecc6683fd03ec793bc126d51cdbee0a72241933136c144f2e602828abddc7e4843df5542a099be92313fa5874d1d2dc54ecdd1ff308c5e

SV = PV(0x104d80b8) at 0x104ec098
  REFCNT = 1
  FLAGS = (PADTMP,POK,pPOK)
  PV = 0x10489170 "flurbe\302\240"\0
  CUR = 8
  LEN = 12
072f7b54c80fa8062ca1d17727a88c9ff4815f83c1166471331c6398b9140a06812eff341c98453f4c51356926dbe9694cbcbebfe4cda7e77cf68008ab838c6d

SV = PV(0x104d80a8) at 0x104f0f98
  REFCNT = 1
  FLAGS = (PADTMP,POK,pPOK,UTF8)
  PV = 0x104896c8 "flurbe\302\240"\0 [UTF8 "flurbe\x{a0}"]
  CUR = 8
  LEN = 12
072f7b54c80fa8062ca1d17727a88c9ff4815f83c1166471331c6398b9140a06812eff341c98453f4c51356926dbe9694cbcbebfe4cda7e77cf68008ab838c6d

如您所见,"$x$y" 的 SHA-512 哈希取决于 $x 是否经过 UTF-8 升级。 "$x$y" 带有 UTF-8 升级的 $x 提供与 "$x$z" 相同的 SHA-512 哈希,带有 non-UTF-8-upgraded $x。这是因为 SHA-512 对字节而不是字符进行操作,并且 UTF-8 升级字符串与字节字符串的连接会导致字节字符串进行 UTF-8 升级。

【讨论】:

    【解决方案2】:

    您有编码问题,即缺少编码。摘要函数在八位字节上运行。你给它字符,这是错误的。

    操作过程:将您的字符编码为八位字节。 UTF-8 是一种合适的编码。

    my $octets = Encode::encode('UTF-8', $characters, Encode::FB_CROAK);
    # add salt to octets
    # produce digest
    
    猜你喜欢
    • 2018-11-05
    • 2011-06-28
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多