如何在perl中完成这个字节调整?
背景:
我正在尝试使用此处的 perl 脚本来解密 android 备份。不幸的是,校验和验证失败。
在玩弄这个 (Python) 脚本之后,问题似乎是我需要对主密钥(masterKeyJavaConversion
Python 脚本中的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] ] }