XOR переменной оболочки и двоичного файла

XOR переменной оболочки и двоичного файла

У меня есть пароль, сохраненный в переменной оболочки (которая была считана из ввода командной строки).

У меня также есть файл ключей, хранящийся в файле (который был создан с помощью ddи /dev/urandom).

Поскольку мне нужно, чтобы оба эти параметра использовались для расшифровки моего жесткого диска, я хотел бы применить к ним операцию XOR, сохранить результат в файле и использовать его в качестве ключа.

Поэтому мне хотелось бы узнать, как проще всего это сделать.

xxdбыло бы идеально, если бы оно позволяло -bи -pв то же время, но, судя по всему, этого не происходит...


Редактировать: Я буду использовать это вhttps://github.com/xavierm02/combine-keys

решение1

Ваша оболочка может обрабатывать побитовые операции, однако для любой серьезной обработки это будетужасномедленно, и не может обрабатывать больше, чем 20 цифр за раз. Тем не менее:

sh <<\CMD 
    printf 'printf "%%b" "\\0$((%04o^04))"'  "'a" |\
    . /dev/stdin
CMD

#OUTPUT
A

bcРаньше я использовал для извлечения байтов в двоичном формате, поэтому ваш вопрос побудил меня поискать в Google...

Исключающее ИЛИ (XOR) для GNU bc

Если вы нашли этот вопрос в Интернете, скорее всего, вы ищете эквивалент ^оператора C в bc.

Тревожный факт: ничего подобного не существует в bc. В bcоператор «стрелка вверх» используется для возведения в степень целых чисел, то есть 2^xвозвращает степень числа 2, а не x с перевернутым битом 2. Если вы ищете эквиваленты побитовым операторам для XOR, а также AND, OR и нескольким более экзотическим родственникам, ознакомьтесь с логикой этого сайта.bc и его родственниками, которые содержат функции для выполнения каждого из них.

Если вы ищете логическое выражение XORдля использования в операторе if, например, логическое &&и ||, попробуйте использовать !=скобки и заключать условия в них. Например:

c=0;if((a==1)!=(b==2)){c=3}

Устанавливает c в 3, если a равно 1 или b равно 2, но не если a равно 1 и b равно 2 одновременно

(Когда-то это был секрет внутреннего устройства функции logic.bc xor(), но теперь он заменен более быстрым алгоритмом.)

Вышеизложенное из bcFAQ. logic.bcФункция, упомянутая выше, включает bitwiseлогику, которую вы ищете. Ее можно найтиздесь. Его описание:

Большой набор функций для выполненияпобитовыйТакие функции, как AND, OR, NOT и XOR. Использует дополнение до двух для отрицательных чисел, в отличие от предыдущих версий этого файла, которые вообще не поддерживались. Некоторые из функций здесь будут использовать глобальную переменную битовой ширины, которая сама по себе инициализируется как часть этого файла, для эмуляции размеров байт/слов, имеющихся в большинстве компьютеров. Если эта переменная установлена ​​в ноль, предполагается бесконечная битовая ширина. Многие функции будут отображать предупреждение, если есть подозрение, что было сгенерировано вторичное представление числа с плавающей точкой, например:

1.1111... is an SFPR of10.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

Связанный контент