ASCII/Unicode文本转二进制及逆转换:Bash脚本pack步骤问题排查
问题分析与解决方案
原步骤的错误点
你提到的ciphertext=$(echo $ciphertext_bin | perl -lpe '$_=pack"B*",$_')存在三个关键问题,导致逆转换不稳定:
echo命令的参数解析问题:如果生成的二进制字符串ciphertext_bin以-开头,echo会将其当作命令选项而非字符串内容处理,直接输出错误结果。perl -l选项的额外换行:-l参数会自动在Perl输出末尾添加换行符,这会给密文额外增加一个字节(换行符),破坏原始密文的完整性。- 未引号包裹变量:虽然当前场景下
ciphertext_bin仅包含0和1,但未用双引号包裹$ciphertext_bin可能在特殊情况下引发意外的字符串分割。
修正后的代码行
将原代码行替换为:
ciphertext=$(printf "%s" "$ciphertext_bin" | perl -pe '$_=pack"B*",$_')
- 使用
printf "%s"替代echo:避免了echo对开头-的误解析,且不会自动添加换行符。 - 移除
-l选项:防止Perl额外添加换行符,保证密文长度与原始明文一致。 - 双引号包裹
$ciphertext_bin:遵循变量引用的最佳实践,避免潜在的字符串处理问题。
更优实现方案
原脚本通过Bash循环逐位XOR的方式效率较低,且容易出错。推荐直接在Perl中完成明文与密钥的XOR操作,完全绕开二进制字符串转换的环节,代码更简洁高效:
#!/bin/bash echo -n "Enter your message:" read plaintext plaintext_size=${#plaintext} # 生成随机密钥 key=$(tr -dc A-Za-z0-9 </dev/urandom | head -c "$plaintext_size") echo "key is $key" # 直接在Perl中完成XOR运算 ciphertext=$(perl -e ' $plaintext = shift; $key = shift; $cipher = ""; for my $i (0 .. length($plaintext)-1) { $cipher .= chr(ord(substr($plaintext, $i, 1)) ^ ord(substr($key, $i, 1))); } print $cipher; ' "$plaintext" "$key") echo "ciphertext is $ciphertext"
这种方式直接对每个字符的ASCII值进行XOR运算,无需转换为二进制字符串,避免了pack/unpack的潜在问题,同时大幅提升处理长文本的效率。
内容的提问来源于stack exchange,提问作者texonec238
相关产品推荐
相关产品推荐

