我有一个密码存储在 shell 变量中(从命令行输入读取)。
我还有一个密钥文件存储在一个文件中(该文件是使用dd
和创建的/dev/urandom
)。
由于我想需要这两个来解密我的硬盘驱动器,因此我想对它们进行异或,将其存储在文件中并将其用作密钥。
因此,我想知道最简单的方法是什么。
xxd
如果允许的话,这将是一个完美的选择-b
,但-p
同时,但显然,它并不......
答案1
你的 shell 可以处理按位操作,但是,对于任何严肃的处理,它都将是非常速度很慢,而且一次只能处理 20 个左右的数字。仍然:
sh <<\CMD
printf 'printf "%%b" "\\0$((%04o^04))"' "'a" |\
. /dev/stdin
CMD
#OUTPUT
A
我bc
过去曾用于抓取二进制字节,所以你的问题让我谷歌搜索......
如果您在互联网上找到了解决这个问题的方法,那么您很可能正在寻找 bc 的相当于 C 的
^
运算符。令人不安的事实:不存在这样的事情
bc
。在 中bc
,向上箭头运算符用于整数求幂,即2^x
返回 2 的幂,而不是 x 的第 2 位翻转。如果您正在寻找 XOR 以及 AND、OR 和一些更奇特的亲属的按位运算符的等效项,请查看此站点的logic.bc 及其包含执行这些操作的函数的亲属。
XOR
如果您正在寻找放入 if 语句的逻辑,例如逻辑&&
and||
,请尝试使用!=
并用方括号括住您的条件。例如:
c=0;if((a==1)!=(b==2)){c=3}
如果 a 为 1 或 b 为 2,则将 c 设置为 3,但如果 a 为 1 且 b 同时为 2,则不会
(曾几何时,这是logic.bc xor() 函数内部的秘密,但这已被更快的算法取代。)
以上摘自bc
常见问题解答。logic.bc
上面提到的函数包括您bitwise
正在寻找的逻辑。可以找到这里。其说明:
执行一大套功能按位函数,例如 AND、OR、NOT 和 XOR。使用二进制补码表示负数,这与此文件的先前版本不同,先前版本根本不支持此操作。此处的一些函数将使用全局位宽变量(该变量本身作为此文件的一部分初始化)来模拟大多数计算机中的字节/字大小。如果将此变量设置为零,则假定位宽为无限大。如果怀疑已生成数字的辅助浮点表示,许多函数将显示警告,例如:
1.1111... is an SFPR of
10.0000...;`可以通过将全局变量设置
sfpr_warn
为0
(默认为 1)来禁用这些警告。
- 固定字号
- 无限字长
- 常见的按位
- 二进制补码
- 位移位
- 格雷码
- '乘法'
- 浮点
- 浮点“乘法”
- 格雷码+浮点
答案2
我使用了 C 二进制文件。
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "No argument given.\n");
exit(1);
}
char *filename = argv[1];
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "Could not open given file.");
exit(1);
}
int c1;
int c2;
do {
c1 = fgetc(stdin);
c2 = fgetc(file);
if (c1 == EOF) {
while (c2 != EOF) {
printf("%c", c2);
c2 = fgetc(file);
}
break;
} else if (c2 == EOF) {
while (c1 != EOF) {
printf("%c", c1);
c1 = fgetc(stdin);
}
break;
}
int c = c1 ^ c2;
printf("%c", c);
} while (true);
exit(0);
}
答案3
我在 SH 几乎可以使用一些东西,但速度太慢了
#!/bin/sh
small_hex_to_bin() {
hex=$1
hex_length=${#1}
bin=$(echo "ibase=16;obase=2;$hex" | bc)
bin_length=$((4*$hex_length))
bin=$(printf %0*d $bin_length $bin)
echo $bin
}
hex_to_bin() {
hex=$1
hex_length=${#hex}
for i in $(seq 1 $hex_length); do
hex_digit=$(expr substr $hex $i 1)
bin_digits=$(small_hex_to_bin $hex_digit)
echo -n $bin_digits
done
echo ""
}
bin_to_hex() {
bin=$1
hex=$(echo "ibase=2;obase=10000;$bin" | bc)
echo $hex
}
char_to_hex() {
char=$1
hex_lower=$(printf %x \'$char\')
hex=$(echo $hex_lower | tr '[:lower:]' '[:upper:]')
echo $hex
}
char_to_bin() {
char=$1
hex=$(char_to_hex $char)
bin=$(small_hex_to_bin $hex)
echo $bin
}
string_to_bin() {
s=$1
l=${#s}
for i in $(seq 1 $l); do
char=$(expr substr $s $i 1)
bin=$(char_to_bin $char)
echo -n $bin
done
echo ""
}
file_to_bin() {
filename=$1
hex_spaces=$(xxd -u -p $filename)
hex=$(echo $hex_spaces | tr -d '\n' | tr -d ' ')
bin=$(hex_to_bin $hex)
echo $bin
}
min() {
if [ $1 -ge $2 ]; then
echo $2
else
echo $1
fi
}
bit_xor() {
if [ $1 -eq $2 ]; then
echo 0
else
echo 1
fi
}
xor() {
b1=$1
b2=$2
l1=${#b1}
l2=${#b2}
l=$(min $l1 $l2)
for i in $(seq 1 $l); do
c1=$(expr substr $b1 $i 1)
c2=$(expr substr $b2 $i 1)
c=$(bit_xor $c1 $c2)
echo -n $c
done
next_i=$(($l + 1))
if [ $l -ne $l1 ]; then
for i in $(seq $next_i $l1); do
c1=$(expr substr $b1 $i 1)
echo -n $c1
done
fi
if [ $l -ne $l2 ]; then
for i in $(seq $next_i $l2); do
c2=$(expr substr $b2 $i 1)
echo -n $c2
done
fi
echo ""
}
#stdin=$(cat)
#file=$(cat $1)
#hex_to_bin $1
file_to_bin $1