如何在perl中完成这个字节调整?

背景:

我正在尝试使用此处的 perl 脚本来解密 android 备份。不幸的是,校验和验证失败。

在玩弄这个 (Python) 脚本之后,问题似乎是我需要对主密钥(masterKeyJavaConversionPython 脚本中的nb )做一些额外的修改。

问题:

我需要带一包字节并执行以下转换步骤:

  • 从有符号字符到有符号短字符的符号扩展
  • 将结果从 UTF16 (BE?) 转换为 UTF-8

例如(所有字节都是十六进制的):

  • 3倍?3倍
  • 7倍?7倍
  • ax -> ef 是 ax
  • bx -> ef 是 bx
  • cx -> ef bf 8x
  • dx -> ef bf 9x
  • ex -> ef bf ax
  • fx -> ef bf bx

x始终保持不变。)

更具体地说,给定一个位序列1abc defg,我需要输出1110 1111 1011 111a 10bc defg. (对于0abc defg,输出只是0abc defg,即不变。)


答案可能会使用 UTF 转换,也可能会直接进行处理;我不在乎,只要它有效(这不是性能关键)。子程序形式的答案是理想的。(我的主要问题是我知道足够多的 Perl 是危险的。如果这是 C/C++,我不需要帮助,但是用另一种语言重写整个脚本或修改 Python 脚本将是一项重大任务不需要将整个输入读入内存。)

回答

1110 1111 1011 111a 10bc defg 将是有效的 UTF-8 编码。

++++-------------------------- Start of three byte sequence
||||     ++------------------- Continuation byte
||||     ||       ++---------- Continuation byte
||||     ||       ||
11101111 1011111a 10bcdefg
    ||||   ||||||   ||||||
    ++++---++++++---++++++---- 1111 1111 1abc defg

这只是将 8 位有符号数扩展为 16 位,转换为无符号数,并被视为 Unicode 代码点。

所以,不看代码,我想你想要

sub encode_utf8 { 
   my ($s) = @_;
   utf8::encode($s);
   return $s;
}

sub munge {
   return
      encode_utf8                # "x30x70xEFxBExA0..."
         pack 'W*',              # "x{0030}x{0x0070}x{0xFFA0}..."
            unpack 'S*',         # 0x0030, 0x0070, 0xFFA0, ...
               pack 's*',        # "x30x00x70x00xA0xFF..." (on a LE machine)
                  unpack 'c*',   # 48, 112, -96, ...
                     $_[0];      # "x30x70xA0..."
}

my $s = "x30x70xA0xB0xC0xD0xE0xF0";
my $munged = munge($s);

如果您删除评论,您将获得以下信息:

sub munge {
   my $s = pack 'W*', unpack 'S*', pack 's*', unpack 'c*', $_[0];
   utf8::encode($s);
   return $s;
}

这是一个更快的解决方案:

my @map = (
   ( map chr($_),            0x00..0x7F ),
   ( map "xEFxBE".chr($_), 0x80..0xBF ),
   ( map "xEFxBF".chr($_), 0xC0..0xFF ),
);

sub munge { join '', @map[ unpack 'C*', $_[0] ] }


以上是如何在perl中完成这个字节调整?的全部内容。
THE END
分享
二维码

)">
< <上一篇
下一篇>>