Tengo una contraseña almacenada en una variable de shell (que se leyó desde la entrada de la línea de comando).
También tengo un archivo de claves almacenado en un archivo (que se creó usando dd
y /dev/urandom
).
Como quiero exigir que ambos descifren mi disco duro, me gustaría realizar un XOR, almacenarlo en un archivo y usarlo como clave.
Por lo tanto, me gustaría saber cuál sería la forma más sencilla de hacerlo.
xxd
encajaría perfectamente si lo permitiera -b
y -p
al mismo tiempo, pero aparentemente no lo hace...
Editar: lo usaré enhttps://github.com/xavierm02/combine-keys
Respuesta1
Su shell puede manejar operaciones bit a bit; sin embargo, para cualquier procesamiento serio, serámuylento y no puede manejar nada más que unos 20 dígitos a la vez. Aún:
sh <<\CMD
printf 'printf "%%b" "\\0$((%04o^04))"' "'a" |\
. /dev/stdin
CMD
#OUTPUT
A
Lo he usado bc
en el pasado para capturar bytes en binario, por lo que tu pregunta me hizo buscar en Google...
Si ha encontrado esta pregunta en Internet, es probable que esté buscando el equivalente de bc al
^
operador de C.Dato inquietante: no existe tal cosa en
bc
. Enbc
, el operador de flecha hacia arriba se usa para la exponenciación de números enteros, es decir,2^x
devuelve una potencia de 2 y no x con el bit 2 invertido. Si está buscando equivalentes a los operadores bit a bit para XOR, así como AND, OR y algunos parientes más exóticos, consulte logic.bc de este sitio y sus parientes que contienen funciones para realizar cada una de estas.Si está buscando una lógica
XOR
para incluir en una declaración if, como lógica&&
y||
, intente usar!=
y rodear sus condiciones entre corchetes. p.ej:
c=0;if((a==1)!=(b==2)){c=3}
Establecerá c en 3, si a es 1 o b es 2, pero no si a es 1 y b es 2 al mismo tiempo.
(Érase una vez, este era el secreto de los aspectos internos de la función logic.bc xor(), pero ha sido reemplazado por un algoritmo más rápido).
Lo anterior es de las bc
preguntas frecuentes. La logic.bc
función mencionada anteriormente incluye la bitwise
lógica que estás buscando. se puede encontraraquí. Su descripción:
Un gran conjunto de funciones para realizarbit a bitfunciones como AND, OR, NOT y XOR. Utiliza complemento a dos para números negativos, a diferencia de las versiones anteriores de este archivo, que no tenían ningún soporte. Algunas de las funciones aquí utilizarán la variable global de ancho de bits, que a su vez se inicializa como parte de este archivo, para emular los tamaños de bytes/palabras que se encuentran en la mayoría de las computadoras. Si esta variable se establece en cero, se supone un ancho de bits infinito. Muchas funciones mostrarán una advertencia si se sospecha que se ha generado una representación secundaria de punto flotante de un número, por ejemplo:
1.1111... is an SFPR of
10.0000...;`Estas advertencias se pueden desactivar configurando la variable global
sfpr_warn
en0
(el valor predeterminado es 1).
- Tamaño de palabra fijo
- Tamaño de palabra infinito
- bit a bit común
- complemento a dos
- cambio de bits
- código gris
- 'Multiplicación'
- Punto flotante
- Punto flotante 'Multiplicación'
- Código Gray + Punto flotante
Respuesta2
Usé un binario 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);
}
Respuesta3
Tengo algo que casi funciona en SH pero es demasiado lento.
#!/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