Eu tenho uma senha armazenada em uma variável shell (que foi lida na entrada da linha de comando).
Eu também tenho um arquivo-chave armazenado em um arquivo (que foi criado usando dd
e /dev/urandom
).
Como quero exigir que ambos descriptografem meu disco rígido, gostaria de fazer um XOR, armazená-lo em um arquivo e usá-lo como chave.
Gostaria, portanto, de saber qual seria a maneira mais simples de fazer isso.
xxd
seria um ajuste perfeito se permitisse -b
e -p
ao mesmo tempo, mas aparentemente não...
Editar: vou usá-lo emhttps://github.com/xavierm02/combine-keys
Responder1
Seu shell pode lidar com operações bit a bit, porém, para qualquer processamento sério, serámuitolento e não consegue lidar com nada além de cerca de 20 dígitos por vez. Ainda:
sh <<\CMD
printf 'printf "%%b" "\\0$((%04o^04))"' "'a" |\
. /dev/stdin
CMD
#OUTPUT
A
Eu usei bc
no passado para capturar bytes em binário, então sua pergunta me levou a pesquisar no Google ...
Exclusivo ou (XOR) para GNU bc
Se você encontrou essa pergunta na Internet, é provável que esteja procurando o equivalente de bc ao
^
operador de C.Fato perturbador: tal coisa não existe em
bc
. Embc
, o operador de seta para cima é usado para exponenciação de inteiros, ou seja,2^x
retorna uma potência de 2 e não x com o bit 2 invertido. Se você está procurando equivalentes aos operadores bit a bit para XOR, bem como AND, OR e mais alguns parentes exóticos, verifique o logic.bc deste site e seus parentes que contêm funções para executar cada um deles.Se você está procurando uma lógica
XOR
para colocar em uma instrução if, como lógico&&
e||
, tente usar!=
e colocar suas condições entre colchetes. por exemplo:
c=0;if((a==1)!=(b==2)){c=3}
Definirá c como 3, se a for 1 ou b for 2, mas não se a for 1 e b for 2 ao mesmo tempo
(Era uma vez, esse era o segredo dos componentes internos da função logic.bc xor(), mas foi substituído por um algoritmo mais rápido.)
O acima é do bc
FAQ. A logic.bc
função mencionada acima inclui a bitwise
lógica que você está procurando. Pode ser encontradoaqui. Sua descrição:
Um grande conjunto de funções para executarbit a bitfunções como AND, OR, NOT e XOR. Usa complemento de dois para números negativos, ao contrário das versões anteriores deste arquivo, que não tinham suporte algum. Algumas das funções aqui usarão a variável global de largura de bits, que é inicializada como parte deste arquivo, para emular tamanhos de bytes/palavras encontrados na maioria dos computadores. Se esta variável for definida como zero, uma largura de bits infinita será assumida. Muitas funções exibirão um aviso se houver suspeita de que uma representação secundária de ponto flutuante de um número foi gerada, por exemplo:
1.1111... is an SFPR of
10,0000...;`Esses avisos podem ser desabilitados definindo a variável global
sfpr_warn
como0
(o padrão é 1).
- Tamanho fixo da palavra
- Tamanho infinito de palavras
- Bit a bit comum
- Complemento de dois
- Mudança de bits
- Código cinza
- 'Multiplicação'
- Ponto flutuante
- Ponto flutuante 'Multiplicação'
- Código cinza + ponto flutuante
Responder2
Eu usei um binário 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);
}
Responder3
Eu tenho algo quase funcionando no SH, mas é muito 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