Reputation: 7809
I'm now doing it this way:
[root@~]# echo Aa|hexdump -v
0000000 6141 000a
0000003
[root@~]# echo -e "\x41\x41\x41\x41"
AAAA
But it's not exactly behaving as I wanted,
the hex form of Aa
should be 4161
,but the output is 6141 000a
,which seems not making sense.
and when performing hex to ascii,is there another utility so that I don't need the prefix \x
?
Upvotes: 69
Views: 219725
Reputation: 71047
Very quick and short:
string='Hello World.' oIFS="$IFS" IFS=$'\n'
printf '%02X\n' ${string//?/$'\n'\'&}; IFS="$oIFS"
Will produce:
48
65
6C
6C
6F
20
57
6F
72
6C
64
2E
Yes, in order to handle space, we have to play with $IFS
.
string='Hello World.' oIFS="$IFS" IFS=$'\n'
printf -v string '%02X\n' ${string//?/$'\n'\'&}; IFS="$oIFS"
mapfile -t array <<<${string%$'\n'}
echo ${array[@]@Q}
'48' '65' '6C' '6C' '6F' '20' '57' '6F' '72' '6C' '64' '2E'
In a function, we could localize $IFS
, things become a little simplier.
ascii2hex() {
local _varname=$1 _string=${*:2} IFS=$'\n'
printf -v _string '%02X\n' ${_string//?/$'\n'\'&}
mapfile -t "$_varname" <<<${_string%$'\n'}
}
ascii2hex myArray 'Hello world!'
echo ${myArray[@]@Q}
'48' '65' '6C' '6C' '6F' '20' '77' '6F' '72' '6C' '64' '21'
Note: as function use ${*:2}
as source string, space don't need to be quoted:
ascii2hex myArray Hello world!
echo ${myArray[@]@Q}
'48' '65' '6C' '6C' '6F' '20' '77' '6F' '72' '6C' '64' '21'
Simply:
printf '%b' ${myArray[@]/#/\\x}
Hello world!
printf -v string '%b' ${myArray[@]/#/\\x}
echo $string
Hello world!
hex2ascii() {
local _array=(${*:2})
printf -v "$1" '%b' ${_array[@]/#/\\x}
}
hex2ascii mystring ${myArray[@]}
echo "$mystring"
Hello world!
Upvotes: 1
Reputation: 154
Finally got the correct thing
echo "Hello, world!" | tr -d '\n' | xxd -ps -c 200
Upvotes: 2
Reputation: 2855
I use:
> echo Aa | tr -d '\n' | xxd -p
4161
> echo 414161 | tr -d '\n' | xxd -r -p
AAa
The tr -d '\n'
will trim any possible newlines in your input
Upvotes: 4
Reputation: 6023
For single line solution:
echo "Hello World" | xxd -ps -c 200 | tr -d '\n'
It will print:
48656c6c6f20576f726c640a
or for files:
cat /path/to/file | xxd -ps -c 200 | tr -d '\n'
For reverse operation:
echo '48656c6c6f20576f726c640a' | xxd -ps -r
It will print:
Hello World
Upvotes: 23
Reputation: 38492
jcomeau@aspire:~$ echo -n The quick brown fox jumps over the lazy dog | python -c "print raw_input().encode('hex'),"
54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67
jcomeau@aspire:~$ echo -n The quick brown fox jumps over the lazy dog | python -c "print raw_input().encode('hex')," | python -c "print raw_input().decode('hex'),"
The quick brown fox jumps over the lazy dog
it could be done with Python3 as well, but differently, and I'm a lazy dog.
Upvotes: 0
Reputation: 11
SteinAir's answer above was helpful to me -- thank you! And below is a way it inspired, to convert hex strings to ascii:
for h in $(echo "4161" | sed "s/\(..\)/\1 /g"); do printf `echo "\x$h"`;done
Aa
Upvotes: 1
Reputation: 1784
With bash :
a=abcdefghij
for ((i=0;i<${#a};i++));do printf %02X \'${a:$i:1};done
6162636465666768696A
Upvotes: 4
Reputation: 106
Text2Conv="Aa"
for letter in $(echo "$Text2Conv" | sed "s/\(.\)/'\1 /g");do printf '%x' "$letter";done
4161
The trick is using sed to parse the Text2Conv to format we can then seperate anf loop using for.
Upvotes: 2
Reputation: 4824
according to http://mylinuxbook.com/hexdump/ you might use the hexdump format parameter
echo Aa | hexdump -C -e '/1 "%02X"'
will return 4161
to add an extra linefeed at the end, append another formatter.
BUT: the format given above will give multiplier outputs for repetitive characters
$ printf "Hello" | hexdump -e '/1 "%02X"'
48656C*
6F
instead of
48656c6c6f
Upvotes: 0
Reputation: 1
echo append a carriage return at the end.
Use
echo -e
to remove the extra 0x0A
Also, hexdump does not work byte-per-byte as default. This is why it shows you bytes in a weird endianess and why it shows you an extra 0x00.
Upvotes: -2
Reputation: 43
here a little script I wrote to convert ascii to hex. hope it helps:
echo '0x'"`echo 'ASCII INPUT GOES HERE' | hexdump -vC | awk 'BEGIN {IFS="\t"} {$1=""; print }' | awk '{sub(/\|.*/,"")}1' | tr -d '\n' | tr -d ' '`" | rev | cut -c 3- | rev
Upvotes: 1
Reputation: 114
I don't know how it crazy it looks but it does the job really well
ascii2hex(){ a="$@";s=0000000;printf "$a" | hexdump | grep "^$s"| sed s/' '//g| sed s/^$s//;}
Created this when I was trying to see my name in HEX ;) use how can you use it :)
Upvotes: 2
Reputation: 39090
The reason is because hexdump
by default prints out 16-bit integers, not bytes. If your system has them, hd
(or hexdump -C
) or xxd
will provide less surprising outputs - if not, od -t x1
is a POSIX-standard way to get byte-by-byte hex output. You can use od -t x1c
to show both the byte hex values and the corresponding letters.
If you have xxd
(which ships with vim), you can use xxd -r
to convert back from hex (from the same format xxd
produces). If you just have plain hex (just the '4161', which is produced by xxd -p
) you can use xxd -r -p
to convert back.
Upvotes: 77
Reputation: 25656
For the first part, try
echo Aa | od -t x1
It prints byte-by-byte
$ echo Aa | od -t x1
0000000 41 61 0a
0000003
The 0a
is the implicit newline that echo produces.
Use echo -n
or printf
instead.
$ printf Aa | od -t x1
0000000 41 61
0000002
Upvotes: 33