XOR einer Shell-Variable und einer Binärdatei

XOR einer Shell-Variable und einer Binärdatei

Ich habe ein Passwort in einer Shell-Variable gespeichert (das aus der Befehlszeilen-Eingabe gelesen wurde).

ddIch habe auch eine Schlüsseldatei in einer Datei gespeichert (die mit und erstellt wurde /dev/urandom).

Da ich zum Entschlüsseln meiner Festplatte beide benötige, würde ich sie gerne mit XOR verknüpfen, in einer Datei speichern und diese als Schlüssel verwenden.

Daher wüsste ich gerne, wie das am einfachsten geht.

xxdwürde perfekt passen, wenn es erlaubt wäre -b, und -pgleichzeitig ist es das aber offensichtlich nicht …


Edit: Ich werde es verwenden inhttps://github.com/xavierm02/combine-keys

Antwort1

Ihre Shell kann bitweise Operationen verarbeiten, für jede ernsthafte Verarbeitung wird sie jedochfurchtbarlangsam und kann nicht mehr als etwa 20 Ziffern gleichzeitig verarbeiten. Trotzdem:

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

#OUTPUT
A

Ich habe es bcin der Vergangenheit zum Erfassen von Bytes im Binärformat verwendet, daher veranlasste mich Ihre Frage dazu, nach ... zu googeln.

Exklusiv-Oder (XOR) für GNU bc

Wenn Sie im Internet zu dieser Frage gefunden haben, suchen Sie wahrscheinlich nach dem bc-Äquivalent des C- ^Operators.

Beunruhigende Tatsache: So etwas gibt es in nicht bc. In bcwird der Aufwärtspfeil-Operator zur Potenzierung ganzer Zahlen verwendet, d. h. 2^xer gibt eine Potenz von 2 zurück und nicht x mit umgekehrtem Bit 2. Wenn Sie nach Äquivalenten zu den bitweisen Operatoren für XOR sowie AND, OR und ein paar exotischere Verwandte suchen, sehen Sie sich logic.bc dieser Site und verwandte Dateien an, die Funktionen zum Ausführen all dieser Operatoren enthalten.

Wenn Sie nach einer logischen Bedingung suchen, XORdie Sie in eine if-Anweisung einfügen können, z. B. „logisch &&und“ ||, versuchen Sie !=, Ihre Bedingungen in Klammern einzuschließen. Beispiel:

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

Setzt c auf 3, wenn a 1 oder b 2 ist, aber nicht, wenn a 1 und b gleichzeitig 2 ist

(Früher war dies das Geheimnis der internen Vorgänge der xor()-Funktion von logic.bc, aber dies wurde durch einen schnelleren Algorithmus ersetzt.)

Das Obige stammt aus den bcFAQ. Die logic.bcoben erwähnte Funktion enthält die bitwisegesuchte Logik. Sie finden sie unterHier. Seine Beschreibung:

Eine große Suite von Funktionen zum AusführenbitweiseFunktionen wie AND, OR, NOT und XOR. Verwendet Zweierkomplement für negative Zahlen, im Gegensatz zu früheren Versionen dieser Datei, die überhaupt keine Unterstützung hatten. Einige der Funktionen hier verwenden die globale Variable „bitwidth“, die selbst als Teil dieser Datei initialisiert wird, um die Byte-/Wortgrößen der meisten Computer zu emulieren. Wenn diese Variable auf Null gesetzt ist, wird eine unendliche Bitbreite angenommen. Viele Funktionen zeigen eine Warnung an, wenn der Verdacht besteht, dass eine sekundäre Gleitkommadarstellung einer Zahl generiert wurde, z. B.:

1.1111... is an SFPR of10.0000...;`

Diese Warnungen können deaktiviert werden, indem die globale Variable sfpr_warnauf gesetzt wird 0 (Standard ist 1).

  • Feste Wortgröße
  • Unendliche Wortgröße
  • Gemeinsame Bitweise
  • Zweierkomplement
  • Bitverschiebung
  • Gray-Code
  • 'Multiplikation'
  • Gleitkomma
  • Gleitkommazahl 'Multiplikation'
  • Gray-Code + Gleitkomma

Antwort2

Ich habe eine C-Binärdatei verwendet.

#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);
}

Antwort3

Ich habe etwas in SH fast zum Laufen gebracht, aber es ist viel zu langsam

#!/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

verwandte Informationen