2010-06-02 15 views
5

Sto provando a realizzare un lavoro nello scripting di Bash. Ho una stringa che voglio XOR con la mia chiave.bit a bit XOR una stringa in Bash

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

teststring="abcdefghijklmnopqr" 

Ora come si XOR il valore di teststring e lo si memorizza in una variabile utilizzando bash?

Qualsiasi aiuto sarà apprezzato.

Fondamentalmente sto cercando di duplicare il risultato di follwing 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

Non sarebbe solo 'teststring =" abcdefghijklmnopqr "^ chiave'? –

+0

che dosen; t lavoro – ricky2002

+0

forse se c'è un modo per passare il valore di teststring in perl da script bash e XOR lì. – ricky2002

risposta

0

Bitwise OR esclusivo in BASH richiede entrambi gli operandi essere numerici. Dato che non esiste un modo integrato per ottenere il valore ordinale (ASCII) di un personaggio in bash, dovrai usare, per esempio, Perl, per ottenere quel valore.

Modifica: come indicato di seguito, ord funziona solo sul primo carattere di una stringa.

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

Naturalmente, una volta che sei in Perl, si potrebbe anche fare tutto lì:

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

Edit: si scopre si può afferrare il valore ordinale di una stringa in BASH utilizzando printf. Basta prefisso la stringa con '.

printf "%d" "'string" 

Così, in BASH solo:

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

ho qualcosa di simile in bash ma la sua visualizzazione 0 come output ... username = 'whoami' test = 'perl -e 'print ord $ strurl^chiave'' echo $ {test} sto facendo qualche errore? – ricky2002

+0

Hai bisogno di racchiudere il comando' perl' in entrambi i backtick o $(). $ strUrl' non è definito, e 'key' è una parola chiave –

+0

È questo il modo corretto per farlo? Sto ottenendo un numero a due cifre come output ma mi aspettavo un numero lungo ber. key = segreta strURL = cdcdcdc strURL = $ (($ (printf "% d" ' "chiave" "strURL")^$ (printf "% d"'))); echo $ strURL – ricky2002

1

Se si decide di andare per Perl one-liner, ecco cosa mi è venuta

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 

funzione di cerniera in Perl 6 farebbe un lavoro migliore ...

4

Con l'aiuto di these hints ho scritto questo script rapidamente per completare la risposta di Pedro:

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

Risultato:

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

Questo è XORing con una chiave di un solo byte. –

0

wok in busybox (la pasta non poteva ricevere due corsi d'acqua), ha fatto anche la chiave da ripetere

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

L'output potrebbe essere qualsiasi valore di byte, 'chr' che produce caratteri di controllo non è una buona idea. Ecco perché il codice nella domanda usa 'Hex' per l'output. –

1

ancora un'altra risposta

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

È possibile utilizzare un ciclo 'data = abcdef; for ((i = 0; i <$ {# data}; i ++)); do printf '% d' "'$ {data: i: 1}"; fatto' per evitare il costrutto complesso usando eval e chiamando un comando esterno 'sed'. –

+0

Come è molto possibile emettere caratteri di controllo con xor, è ragionevole presentare il risultato codificato come cifre esadecimali (come la domanda). –

+0

@JosEduSol In realtà, questa è una soluzione ragionevole alla domanda posta: uno script bash per xor due stringhe (come valori ascii). in tal senso, cambia 'printf" \\\\\\% o "" $ {_ res [@]} "| xargs printf' al più semplice 'printf '% 02x'" $ {_ res [@]} "' –

0

il più simile trasformazione solo la funzione di bash potrebbe essere:
(# significa commento):

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

Rimozione dei commenti, e la pulizia del codice:

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

Eseguendolo:

$ ./script.sh "123456789" "abcdefghijklmnopqr" 
5050505050505050505b595f595b5947494b