shell 變數和二進位檔案的異或

shell 變數和二進位檔案的異或

我有一個密碼儲存在 shell 變數中(從命令列輸入讀取)。

我還有一個密鑰檔案儲存在一個檔案中(該檔案是使用dd和建立的/dev/urandom)。

由於我想需要這兩個來解密我的硬碟驅動器,因此我想對它們進行異或,將其儲存在文件中並將其用作金鑰。

因此,我想知道最簡單的方法是什麼。

xxd如果允許的話,這將是一個完美的選擇-b,但-p同時,但顯然,它並不......


編輯:我將使用它https://github.com/xavierm02/combine-keys

答案1

你的 shell 可以處理位元操作,但是,對於任何嚴肅的處理,它將是非常速度很慢,一次只能處理 20 個左右的數字。仍然:

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

#OUTPUT
A

bc過去曾用於抓取二進位字節,所以你的問題讓我谷歌搜尋...

GNU bc 的異或 (XOR)

如果您在網路上找到了解決這個問題的方法,那麼您很可能正在尋找 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 of10.0000...;`

可以透過將全域變數設為sfpr_warn0 預設為 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

相關內容