使用 bash 反转文件中位的最快命令是什么

what is the quickest command to reverse bits in file using bash

我想编写一个 bash 脚本来更改文件中的位。我创建了 txt 文件,然后使用了 md5,现在我想更改一个或两个位(我向 运行 okteta 发出命令并在那里更改,但我想尝试不使用它)到更新文件上的 运行 md5看看哈希值是否不同

#!/bin/bash
echo "input file:"
read file_input
echo "choose algorythm ( md5(1) or sha256(2) )"
read choice
if [ $choice -eq 1 ]
then
    echo "running md5"
    openssl dgst -md5 $file_input > md5.txt
    FILENAME=/home/lukasz/$file_input
    FILESIZE=$(stat -c%s "$FILENAME")
    echo "size of the input file : $FILESIZE"
    hexdump -C $file_input
    echo "process of changing bits..."
    echo "how many bit do u want to change?"
    read num
    while [ $num -gt 0 ]
    do
        echo "which bit do u want to change?"
        read number
        # no idea 
        num=$(( $num - 1 ))
   done
   # okteta $file_input > testowyMD5.    
   cmp -l md5.txt md5PO.txt | grep "" -c

else
   echo 'hello'
fi

请您尝试以下 bash 脚本。它反转 bitfile 中的第 pos 个字节。嵌入命令将很容易 在您的 bash 脚本中。请注意,您需要将 pos 分配给某个值 即使您不打算让用户输入它。

#!/bin/bash

# these values are for demonstration
pos=16                  # position (address) of the byte to modify. 0 <= $pos <= filesize - 1
bit=2                   # bit slice to flip. 0 <= $bit <= 7
file="thisfile"         # filename to modify

int=$(( 16#$(dd if="$file" bs=1 skip="$pos" count=1 2> /dev/null | xxd -p) ))
(( mask = 1 << bit ))
(( int = int ^ mask ))
printf "%02x" "$int" | xxd -r -p | dd of="$file" bs=1 seek="$pos" conv=notrunc 2> /dev/null
  • dd if="$file" bs=1 skip="$pos" count=1读取指定地址的一个字节。
  • xxd -p将字节(字符)转换为十六进制字符串。
  • 16#$( commands above ) 将十六进制字符串转换为 0 到 255 之间的整数值。
  • (( mask = 1 << bit )) 生成位掩码以反转指定位。
  • (( int = int ^ mask )) 反转位。
  • 最后的printf ...将字节按相反的顺序写入。

[编辑]
这是易于处理的功能化版本:

#!/bin/bash

# usage: bitflip filename pos bit ...
#        bit is variable length arguments and can be put as many as you want
bitflip() {
    local file=; shift        # 1st argument
    local pos=; shift         # 2nd argument
    local -a bits=("$@")        # 3rd and remaining arguments (if any)

    local int mask bit

    int=$(( 16#$(dd if="$file" bs=1 skip="$pos" count=1 2> /dev/null | xxd -p) ))
    for bit in "${bits[@]}"; do
        (( mask = 1 << bit ))
        (( int = int ^ mask ))
    done
    printf "%02x" "$int" | xxd -r -p | dd of="$file" bs=1 seek="$pos" conv=notrunc 2> /dev/null
}

# demonstration of simple usage
bitflip thisfile 16 2

# multiple bit parameters to invert 0th and 2nd bit at once
bitflip thisfile 16 0 2

# you can also call it multiple times in a loop
for i in 0 2; do
    bitflip thisfile 16 "$i"
done

那么您的主要代码将如下所示:

echo "how many bits do you want to change"
read NUMBER
while (( NUMBER-- > 0 ))
do
    echo "put the number of the byte in which you want to change a bit ( 0 <= X <= $MAX_VALUE)"
    read BYTE_NUMBER
    echo "now choose the bit you want to reverse ( 0 <= X <= 7 )"
    read BIT_NUMBER
    bitflip "copy_org.txt" "$BYTE_NUMBER" "$BIT_NUMBER"
done

请注意它总是覆盖文件。如果需要,您可能需要提前备份。