LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-30-2006, 08:01 PM   #1
//////
Member
 
Registered: Nov 2005
Location: Land of Linux :: Finland
Distribution: Arch Linux && OpenBSD 7.4 && Pop!_OS && Kali && Qubes-Os
Posts: 824

Rep: Reputation: 350Reputation: 350Reputation: 350Reputation: 350
[bash] ASCII to HEX and hex to ascii


What kind of command should I use to translate ascii to hex in a bash script ? (and hex back to ascii)

TIA

/////
 
Old 09-30-2006, 08:30 PM   #2
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
do you mean something like this?
Code:
echo 0x41 | awk '{printf "%c\n", $1}'
A
The other direction (like an "ord(char)" function), is much less straightforward. Here are a couple of interesting solutions:

http://devworld.apple.com/documentat...section_3.html

And here's yet another possibility:
Code:
echo A|hexdump
0000000 0a41
0000002
... or, equivalently ...
Code:
echo A|od -x
0000000 0a41
0000002

Last edited by paulsm4; 09-30-2006 at 08:42 PM.
 
Old 09-30-2006, 08:53 PM   #3
//////
Member
 
Registered: Nov 2005
Location: Land of Linux :: Finland
Distribution: Arch Linux && OpenBSD 7.4 && Pop!_OS && Kali && Qubes-Os
Posts: 824

Original Poster
Rep: Reputation: 350Reputation: 350Reputation: 350Reputation: 350
Hi, yes something like that. Only but is that..
Code:
echo 0x41 | awk '{printf "%c\n", $1}'
0
..this doesn't work in my box
awk -W version
GNU Awk 3.1.5
Code:
awk '{printf "%c\n", $1}' /root/Desktop/testfile # testfile contains 0x41
0
it woold be good if it worked with words, not just single letters.

Cheers

////

Edit: Thank you, I can use that hexdump, and that link is a nice one

Last edited by //////; 09-30-2006 at 09:07 PM.
 
Old 10-01-2006, 07:48 AM   #4
spirit receiver
Member
 
Registered: May 2006
Location: Frankfurt, Germany
Distribution: SUSE 10.2
Posts: 424

Rep: Reputation: 33
Quote:
Originally Posted by //////
..this doesn't work in my box
Try the following instead (with Bash):
Code:
ada@barnabas:~> echo -e "\x41" | awk '{printf "%c\n", $1}'
A
Edit: Sorry, I guess this is nonsense.

Last edited by spirit receiver; 10-01-2006 at 07:56 AM.
 
Old 10-01-2006, 08:50 AM   #5
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
alternative in Python:

ascii to hex:

Code:
#!/usr/bin/python
hex(ord('a'))
output:
'0x61'

hex to ascii
Code:
import binascii
binascii.a2b_hex("61")
output:
'a'
 
Old 10-01-2006, 09:12 AM   #6
spirit receiver
Member
 
Registered: May 2006
Location: Frankfurt, Germany
Distribution: SUSE 10.2
Posts: 424

Rep: Reputation: 33
... and I just learned that there's a package named uni2ascii which does the following:
Code:
ada@barnabas:~> echo "ABCDE" | uni2ascii -Bsepq
\x0041\x0042\x0043\x0044\x0045
ada@barnabas:~> echo "ABCDE" | uni2ascii -Bsepq | ascii2uni -Bq
ABCDE
 
Old 10-01-2006, 09:55 AM   #7
//////
Member
 
Registered: Nov 2005
Location: Land of Linux :: Finland
Distribution: Arch Linux && OpenBSD 7.4 && Pop!_OS && Kali && Qubes-Os
Posts: 824

Original Poster
Rep: Reputation: 350Reputation: 350Reputation: 350Reputation: 350
Quote:
Originally Posted by spirit receiver
... and I just learned that there's a package named uni2ascii which does the following:
Code:
ada@barnabas:~> echo "ABCDE" | uni2ascii -Bsepq
\x0041\x0042\x0043\x0044\x0045
ada@barnabas:~> echo "ABCDE" | uni2ascii -Bsepq | ascii2uni -Bq
ABCDE
Thanks guys, that uni2ascii is a good one, just compiled it and it does its job nicely.
 
Old 10-01-2006, 11:18 AM   #8
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
There's a nice utility that comes with Vim called xxd. It is script-friendly, and (unlike od or hexdump) has the ability to go back and forth (with the revert option).

For example, you could have something like:
Code:
... | xxd -g 1 -c 1 | awk ...
Where there are three fields you can access in awk. $1 is the offset (in hex), $2 is the two-digit hex representation of a byte, and $3 is the ASCII representation of the byte (or just a period for nonprintable characters).

For going back, just do something like:
Code:
... | xxd -p -s -
The only formatting restrictions on the input is that single bytes appear together as two-digit numbers. It doesn't care about formatting or whitespace (the -p is for plain).

I guess xxd's not as portable as hexdump or od, but it is probably more portable than uni2ascii (i.e., is more likely to be found installed on a *nix machine than uni2ascii).
 
Old 10-01-2006, 11:44 AM   #9
//////
Member
 
Registered: Nov 2005
Location: Land of Linux :: Finland
Distribution: Arch Linux && OpenBSD 7.4 && Pop!_OS && Kali && Qubes-Os
Posts: 824

Original Poster
Rep: Reputation: 350Reputation: 350Reputation: 350Reputation: 350
Quote:
Originally Posted by osor
I guess xxd's not as portable as hexdump or od, but it is probably more portable than uni2ascii (i.e., is more likely to be found installed on a *nix machine than uni2ascii).
Thats true, but I'm not that concerned about portability, (I'm using slax based Back|Track and adding modules is easy) and I'm not doing anything really important, just learning to write my own snort rules and I was getting tired to visit online hex translators

But anyways, that ascii2hex is working nicely with my script so thanks again.

Code:
slax ~ # /root/Desktop/trans 'Hello there !'
48 65 6C 6C 6F 20 74 68 65 72 65 20 21
 
Old 06-14-2010, 06:48 PM   #10
gsm123
LQ Newbie
 
Registered: Jun 2010
Posts: 1

Rep: Reputation: 0
Another awk alternative with more than one character

Code:
echo -e "\x41\x20\x42\x20\x43" | awk '{printf "%s\n", $_}'
gives

Quote:
A B C
 
Old 05-13-2013, 09:31 AM   #11
SPF
Member
 
Registered: Jul 2007
Location: /home
Distribution: Debian
Posts: 37

Rep: Reputation: 15
What if your string is:
48656C6C6F2074686572652021

And you don't have perl, python, xxd or uni2ascii?
And you are not allowed to install it.

How can you convert it?

Or course I could always write a loop and read it in pairs:

Code:
#!/bin/bash
function hex2string () {
  I=0
  while [ $I -lt ${#1} ];
  do
    echo -en "\x"${1:$I:2}
    let "I += 2"
  done
}
hex2string "48656C6C6F2074686572652021"
 
Old 05-15-2013, 02:26 PM   #12
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Hex to ascii is dead easy; bash can do it internally, if they're properly formatted. Just use "echo -e", printf's %b format token, or the $'..' quoting form. See the sections on QUOTING and the echo built-in in the bash man page for full details on what these options can expand.

So in post #10 above, the awk command is actually completely superfluous. The characters are converted by echo before they even reach it.

As for the reverse direction, there's no built-in way to do it, so see the above. I've also used uniname before to get the hex codes of a string of characters.

Edit: Example use for the string in #9:

Code:
$ hexchars=( 48 65 6C 6C 6F 20 74 68 65 72 65 20 21 )
$ ( IFS='' ; printf '%b\n' "${hexchars[*]/#/\x}" )
Hello there !
I used a '(..)' subshell in order to keep the IFS setting local. It's needed in order to print the '*' expansion without spaces between each entry. Changing '*' to '@' would print every character on a separate line.

Last edited by David the H.; 05-15-2013 at 02:36 PM. Reason: as stated
 
Old 06-02-2013, 04:50 PM   #13
peetaur
LQ Newbie
 
Registered: Nov 2011
Posts: 3

Rep: Reputation: Disabled
You guys with awk are silly... your awk is not doing anything at all. Sorry to point that out. :P

Code:
$ echo -e "\x41\x20\x42\x20\x43" |cat
A B C
$ echo -e "\x41\x20\x42\x20\x43" | awk '{printf "%s\n", $_}'
A B C
 
Old 03-20-2014, 10:21 AM   #14
es131245
LQ Newbie
 
Registered: Mar 2014
Posts: 19

Rep: Reputation: Disabled
Code:
#!/bin/sh
echo -e "\x41\x20\x42\x20\x43" | cat
echo -e "\x41\x20\x42\x20\x43" | awk '{printf "%s\n", $_}'
exit
Code:
"try.sh" 25 lines, 893 characters
\x41\x20\x42\x20\x43
awk: illegal field $(), name "_"
 input record number 1, file 
 source line number 1
Code:
uname -a
FreeBSD host.com 10.0-RELEASE FreeBSD 10.0-RELEASE #0 r260789: Thu Jan 16 22:34:59 UTC 2014     root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64

Last edited by es131245; 03-22-2014 at 02:59 AM.
 
Old 03-20-2014, 12:43 PM   #15
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
Quote:
Originally Posted by es131245 View Post
Code:
#!/bin/sh
echo -e "\x41\x20\x42\x20\x43" | cat
echo -e "\x41\x20\x42\x20\x43" | awk '{printf "%s\n", $_}'
exit
Code:
"try.sh" 25 lines, 893 characters
\x41\x20\x42\x20\x43
awk: illegal field $(), name "_"
 input record number 1, file 
 source line number 1
Code:
uname -a
FreeBSD y-es.ru 10.0-RELEASE FreeBSD 10.0-RELEASE #0 r260789: Thu Jan 16 22:34:59 UTC 2014     root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
Works fine for me with both bash and sh. It looks to me like you have an outdated version of awk that doesn't support "$_", but I have no experience with FreeBSD. I'm running GNU awk 3.1.8

Last edited by suicidaleggroll; 03-20-2014 at 12:44 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Converting extended ascii (ë,ô) in bash script Hko Programming 4 12-29-2012 03:42 AM
How do i write to a serial port (modem) in ascii or hex directly? Taliesin.duchaos Linux - Networking 6 04-21-2006 08:31 AM
Hex socks Linux - General 4 02-17-2005 12:05 PM
bash printing extended ASCII characters nutthick Programming 6 02-04-2005 02:15 PM
Binary to Hex Ascii converter carboncopy Slackware 1 05-28-2004 09:09 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration