2010-06-02 24 views
5

Tôi đang cố gắng hoàn thành một tác phẩm trong kịch bản lệnh Bash. Tôi có một chuỗi mà tôi muốn XOR với chìa khóa của tôi.bitwise XOR một chuỗi trong Bash

#!/bin/sh 
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH 

teststring="abcdefghijklmnopqr" 

Bây giờ, làm thế nào để XOR giá trị của chuỗi thử nghiệm và lưu trữ nó bằng biến bash?

Mọi trợ giúp sẽ được đánh giá cao.

Về cơ bản tôi đang cố gắng để lặp lại trong các kết quả những công đọan VB Script:

Function XOREncryption(CodeKey, DataIn) 

Dim lonDataPtr 
Dim strDataOut 
Dim temp 
Dim tempstring 
Dim intXOrValue1 
Dim intXOrValue2 


For lonDataPtr = 1 To Len(DataIn) Step 1 
    'The first value to be XOr-ed comes from the data to be encrypted 
    intXOrValue1 = Asc(Mid(DataIn, lonDataPtr, 1)) 
    'The second value comes from the code key 
    intXOrValue2 = Asc(Mid(CodeKey, ((lonDataPtr Mod Len(CodeKey)) + 1), 1)) 

    temp = (intXOrValue1 Xor intXOrValue2) 
    tempstring = Hex(temp) 
    If Len(tempstring) = 1 Then tempstring = "0" & tempstring 

    strDataOut = strDataOut + tempstring 
Next 
XOREncryption = strDataOut 
End Function 
+0

Nó sẽ không chỉ là 'teststring =" abcdefghijklmnopqr "^ key'? –

+0

mà dosen; t làm việc – ricky2002

+0

có thể nếu có một số cách để vượt qua giá trị của chuỗi test trong perl từ bash script và XOR nó ở đó. – ricky2002

Trả lời

0

Bitwise độc ​​quyền-OR trong BASH đòi hỏi cả hai toán hạng phải là số. Vì không có cách tích hợp để nhận giá trị thứ tự (ASCII) của một ký tự trong bash, bạn sẽ cần sử dụng Perl để lấy giá trị đó.

Chỉnh sửa: như đã nêu bên dưới, ord chỉ hoạt động trên ký tự đầu tiên của chuỗi.

let a=`perl -e 'print ord $_ for split //, $ARGV[0]' string`^123; echo $a 

Tất nhiên, một khi bạn đang ở trong Perl, bạn cũng có thể làm tất cả có:

let a=`perl -e '$ordinal .= ord $_ for split //, $ARGV[0]; print $ordinal^$ARGV[1]' string 123` 

Sửa: nó quay ra bạn có thể lấy các giá trị thứ tự của một chuỗi trong BASH sử dụng printf. Đơn giản chỉ cần tiền tố chuỗi với '.

printf "%d" "'string" 

Vì vậy, chỉ trong BASH:

let a=$(printf "%d" "'string")^123; echo $a 
+0

Tôi có một cái gì đó như thế này trong bash nhưng hiển thị 0 là đầu ra ... username = 'whoami' test = 'perl -e 'print ord $ strUrl^key'' echo $ {test} Tôi có mắc lỗi gì không? – ricky2002

+0

Bạn cần bọc lệnh' perl' vào cả hai dấu backticks hoặc $(). Ngoài ra, ' $ strUrl' là undefined, và 'key' là một bareword –

+0

Đây có phải là cách thích hợp để làm điều đó không? Tôi đang nhận được một số có hai chữ số như đầu ra nhưng tôi đã mong đợi một số dài ber. key = bí mật strUrl = cdcdcdc strUrl = $ (($ (printf "% d" " 'strUrl")^$ (printf "% d" "' chìa khóa"))); echo $ strUrl – ricky2002

1

Nếu bạn quyết định để đi cho Perl one-liner, đây là những gì tôi đã đưa ra

chức năng zip
perl -e '@a=split("", $ARGV[0]); @b=split("", $ARGV[1]); print unpack "H2", chr(ord(shift @a)^ord(shift @b)) while @a; print "\n"' aab aaa 

trong Perl 6 sẽ làm tốt hơn ...

4

Với sự giúp đỡ của these hints i viết này nhanh chóng kịch bản để hoàn thành Pedro của câu trả lời:

#!/bin/bash 

function ascii2dec 
{ 
    RES="" 
    for i in `echo $1 | sed "s/./& /g"` 
    do 
    RES="$RES `printf \"%d\" \"'$i\"`" 
    done 
    echo $RES 
} 

function dec2ascii 
{ 
    RES="" 
    for i in $* 
    do 
    RES="$RES`printf \\\\$(printf '%03o' $i)`" 
    done 
    echo $RES 
} 

function xor 
{ 
    KEY=$1 
    shift 
    RES="" 
    for i in $* 
    do 
    RES="$RES $(($i ^$KEY))" 
    done 

    echo $RES 
} 


KEY=127 
TESTSTRING="abcdefghijklmnopqr" 

echo "Original String: $TESTSTRING" 
STR_DATA=`ascii2dec "$TESTSTRING"` 
echo "Original String Data: $STR_DATA" 
XORED_DATA=`xor $KEY $STR_DATA` 
echo "XOR-ed Data: $XORED_DATA" 
RESTORED_DATA=`xor $KEY $XORED_DATA` 
echo "Restored Data: $RESTORED_DATA" 
RESTORED_STR=`dec2ascii $RESTORED_DATA` 
echo "Restored String: $RESTORED_STR" 

Kết quả:

iMac:Desktop fer$ bash test.sh 
Original String: abcdefghijklmnopqr 
Original String Data: 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 
XOR-ed Data: 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 
Restored Data: 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 
Restored String: abcdefghijklmnopqr 
+0

Đây là XOR với khóa chỉ có một byte. –

0

woks trong busybox (dán không thể nhận được hai con suối), cũng làm chìa khóa để lặp lại

#!/bin/sh 
numitems() { i=0;while read ITEM; do i=$(($i + 1)) ; done; echo $i; } 
starmap() { while read ITEM; do $1 $ITEM; done; } 
ord() { printf '%d\n' "'$1"; } 
chr() { printf \\$(printf '%03o' $1); } 
split_chars() { echo -n "$1" | sed 's/./&\n/g'; } 
xor() { echo $(($1^$2)); } 
map_ord() { split_chars "$1" | starmap ord; } 
encrypt() 
{ 
KEY=$1;STR=$2; 
while [ ${#KEY} -lt ${#STR} ]; do KEY="$KEY$KEY"; done; #make key longer then str 
[ -e /tmp/paste_col1 ] && rm -rf /tmp/paste_col1 
[ -e /tmp/paste_col1t ] && rm -rf /tmp/paste_col1t 
[ -e /tmp/paste_col2 ] && rm -rf /tmp/paste_col2 
map_ord "$KEY">/tmp/paste_col1t 
map_ord "$STR">/tmp/paste_col2 
head -n `wc -l /tmp/paste_col2 |sed -r 's|^([0-9]+)\s.*|\1|'` /tmp/paste_col1t>/tmp/paste_col1 #trim lines 
[ -e /tmp/paste_col1t ] && rm -rf /tmp/paste_col1t 
paste /tmp/paste_col1 /tmp/paste_col2 | starmap xor | starmap chr 
[ -e /tmp/paste_col1 ] && rm -rf /tmp/paste_col1 
[ -e /tmp/paste_col2 ] && rm -rf /tmp/paste_col2 
echo 
} 
KEY="12345678" 
TESTSTRING="abcdefghasdfasdfasfdas" 
encrypt "$KEY" "$TESTSTRING" 
ENC="`encrypt \"$KEY\" \"$TESTSTRING\"`" 
encrypt "$KEY" "$ENC" # we should get $TESTSTRING again 
+0

Đầu ra có thể là bất kỳ giá trị byte nào, 'chr' tạo ra các ký tự điều khiển không phải là một ý tưởng hay. Đó là lý do tại sao mã trong câu hỏi sử dụng 'Hex' cho đầu ra. –

1

chưa có câu trả lời nào khác

function xenc { 
    local data=$1 key=$2 
    local _data _key ndata nkey count i _res 
    _data=($(eval printf "'%d '" $(printf "%s" "$data" | sed -e '$!N;${s/./"'"'"'&" /g;s/""/\\&/g}'))) 
    _key=($(eval printf "'%d '" $(printf "%s" "$key" | sed '$!N;${s/./"'"'"'&" /g;s/""/\\&/g}'))) 
    ndata=${#_data[@]} nkey=${#_key[@]} 
    ((count = ndata < nkey ? nkey : ndata)) 
    for ((i = 0; i < count; i++)); do 
    ((_res[i] = ${_data[i]:-0}^${_key[i%nkey]:-0})) 
    done 
    printf "\\\\\\%o" "${_res[@]}" | xargs printf 
} 
res=$(xenc abcdefghijklmnopqrstuvwxyz FLqFb8LU0TY) 
xenc "$res" FLqFb8LU0TY 
+0

Bạn có thể sử dụng vòng lặp 'data = abcdef; cho ((i = 0; i <$ {# dữ liệu}; i ++)); làm printf '% d' "'$ {dữ liệu: i: 1}"; done' để tránh việc xây dựng phức tạp bằng cách sử dụng eval và gọi một lệnh bên ngoài 'sed'. –

+0

Như rất có thể phát ra các ký tự điều khiển với xor, nó là hợp lý để trình bày kết quả được mã hóa dưới dạng chữ số hex (như yêu cầu câu hỏi). –

+0

@JosEduSol Trong thực tế, đây là một giải pháp hợp lý cho câu hỏi được hỏi: Một tập lệnh bash để xor hai chuỗi (như giá trị ascii). để có hiệu lực đó, thay đổi 'printf" \\\\\\\\\\\\\\\\ "" {{res res [@]} "| xargs printf' vào 'printf '% 02x'" $ {_ res [@]} "đơn giản hơn –

0

Việc chuyển đổi tương tự như hầu hết chỉ có chức năng để bash sẽ là:
(# có nghĩa là bình luận):

# Function XOREncryption(CodeKey, DataIn) 
XOREncryption(){ 
    local CodeKey=$1 
    local DataIn=$2 
    # Dim lonDataPtr strDataOut temp tempstring intXOrValue1 intXOrValue2 
    local lonDataPtr strDataOut temp tempstring intXOrValue1 intXOrValue2 

    # For lonDataPtr = 1 To Len(DataIn) Step 1 
    for ((lonDataPtr=0; lonDataPtr < ${#DataIn}; lonDataPtr++)); do 
     #The first value to be XOr-ed comes from the data to be encrypted 
    # intXOrValue1 = Asc(Mid(DataIn, lonDataPtr, 1)) 
    intXOrValue1=$(toAsc "${DataIn:$lonDataPtr:1}") 
    echo "val1=$intXOrValue1 and=<${DataIn:$lonDataPtr:1}> and $(toAsc "${DataIn:$lonDataPtr:1}")" 
     #The second value comes from the code key 
    echo "Ptr=$lonDataPtr Mod=<$((lonDataPtr % ${#CodeKey}))>" 
    # intXOrValue2 = Asc(Mid(CodeKey, ((lonDataPtr Mod Len(CodeKey)) + 1), 1)) 
    intXOrValue2=$(toAsc "${CodeKey:$((lonDataPtr % ${#CodeKey})):1}") 
    echo "val1=$intXOrValue1 val2=<${CodeKey:$((lonDataPtr % ${#CodeKey})):1}> and |$intXOrValue2|" 
    # temp = (intXOrValue1 Xor intXOrValue2) 
    temp=$((intXOrValue1^intXOrValue2)) 
    echo "temp=$temp" 
     # tempstring = Hex(temp) 
    tempstring=$(printf '%02x' "$temp") 
    echo "tempstring=$tempstring" 
    # strDataOut = strDataOut + tempstring 
     strDataOut+=$tempstring 
    echo 
    # Next 
    done 
    # XOREncryption = strDataOut 
    printf '%s\n' "$strDataOut" 
# End Function 
} 

Loại bỏ các ý kiến, và làm sạch mã:

#!/bin/bash 

Asc() { printf '%d' "'$1"; } 

XOREncryption(){ 
    local key=$1 DataIn=$2 
    local ptr DataOut val1 val2 

    for ((ptr=0; ptr < ${#DataIn}; ptr++)); do 
     val1=$(Asc "${DataIn:$ptr:1}") 
     val2=$(Asc "${key:$((ptr % ${#key})):1}") 
     DataOut+=$(printf '%02x' "$((val1^val2))") 
    done 
    printf '%s\n' "$DataOut" 
} 

CodeKey="$1" 
teststring="$2" 
XOREncryption "$CodeKey" "$teststring" 

Chạy:

$ ./script.sh "123456789" "abcdefghijklmnopqr" 
5050505050505050505b595f595b5947494b 
Các vấn đề liên quan