output hex data from xattr to create icns file - bash

I'm trying to extract the icon from an xattr of a file.
Using xattr to get the "com.apple.ResourceFork" in hex format i use:
xattr -px com.apple.ResourceFork file
and save the output to a variable
var="$(xattr -px com.apple.ResourceFork file)"
then using variable expansion i remove the first bytes until i reach 69 (icns magic number is 69 63 6E 73)
var=${var#*69 63 6E 73}
next i output the variable and append "69 63 6E 73" to the beginning to restore the magic number.
echo "69 63 6E 73$var" > output.txt
if i take the hex data from the output.txt and insert it into a hexeditor to save it then it works and the .icns is created.
i want to do this programmatically in bash/zsh without having to save it manually.
tried using
touch icon.icns
to create an empty file then
echo "69 63 6E 73$var" > icon.icns
just transforms the output file into an ASCII file.
i'm not stuck to my method, any working method is acceptable to me.

I have access to my Mac again... strangely (to me) it seems xxd works differently when given parameters all together rather than individually, so rather than what I suggested in the comments:
xxd -rp ...
you would need:
xxd -r -p ...
As I don't have an icon.icns file to hand, I'll take a JPEG (which is just as binary), convert it to readable hex and reconstruct it from the hex with xxd.
Here's a JPEG, converted to hex:
xxd x.jpg | more
00000000: ffd8 ffe0 0010 4a46 4946 0001 0100 0001 ......JFIF......
00000010: 0001 0000 ffdb 0043 0003 0202 0202 0203 .......C........
...
...
Then take the hex and give reconstruct the first few bytes of the JPEG:
printf "ff d8 ff e0" | xxd -r -p > recreated.jpg
And look at the recreated file:
xxd recreated.jpg
00000000: ffd8 ffe0
So the process for a while file would be:
hex=$(xxd -p x.jpg)
printf "$hex" | xxd -r -p > recreated.jpg

Related

In Unix shell, how to convert from hex string to stdout bytes in machine-endian order

I'd like to run a command similar to:
# echo 00: 0123456789abcdef | xxd -r | od -tx1
0000000 01 23 45 67 89 ab cd ef
0000010
That is, I'd like to input a hex string and have it converted to bytes on stdout. However, I'd like it to respect byte order of the machine I'm on, which is little endian. Here's the proof:
# lscpu | grep Byte.Order
Byte Order: Little Endian
So, I'd like it to work as above if my machine was big-endian. But since it isn't, I'd like to see:
# <something different here> | od -tx1
0000000 ef cd ab 89 67 45 23 01
0000010
Now, xxd has a "-e" option for little endianess. But 1) I want machine endianess, because I'd like something that works on big or little endian machines, and 2) "-e" isn't support with "-r" anyway.
Thanks!
What about this —
$ echo 00: 0123456789abcdef | xxd -r | xxd -g 8 -e | xxd -r | od -tx1
0000000 ef cd ab 89 67 45 23 01
0000010
According to man xxd:
-e
Switch to little-endian hexdump. This option treats byte groups as words in little-endian byte order. The default grouping of 4 bytes may be changed using -g. This option only applies to hexdump, leaving the ASCII (or EBCDIC) representation unchanged. The command line switches -r, -p, -i do not work with this mode.
-g bytes | -groupsize bytes
Separate the output of every bytes bytes (two hex characters or eight bit-digits each) by a whitespace. Specify -g 0 to suppress grouping. Bytes defaults to 2 in normal mode, 4 in little-endian mode and 1 in bits mode. Grouping does not apply to postscript or include style.

In Bash, how to convert only extended ASCII chars to their hex codes?

I need to check my string variable for presence of extended ASCII characters, one byte, decimal code 128-255. If any is there, replace it with multiple character hex equivalent, ready for further grep command etc.
Example string: "Ørsted\ Salg", I need it to be converted to "\xD8rsted\ Salg".
I know the way to do it with hastable in Bash 4:
declare -A symbolHashTable=(
["Ø"]="D8"
);
currSearchTerm="Ørsted\ Salg"
for curRow in "${!symbolHashTable[#]}"; do
currSearchTerm=$(echo $currSearchTerm | sed s/$curRow/'\\x'${symbolHashTable[$curRow]}/)
done
, but that seems too tedious for 127 cases. There should be a way to do it shorter and probably faster, without writing all the symbols.
I can detect whether the string has any of the characters in it with:
echo $currSearchTerm | grep -P "[\x80-\xFF]"
I am almost sure there is a way to make sed do it, but I get lost somewhere in the "replace with" part.
You can easily do this with Perl:
#!/bin/bash
original='Ørsted'
replaced=$(perl -pe 's/([\x80-\xFF])/"\\x".unpack "H*", $1/eg' <<< "$original")
echo "The original variable's hex encoding is:"
od -t x1 <<< "$original"
echo "Therefore I converted $original into $replaced"
Here's the output when the file and terminal is ISO-8859-1:
The original variable's hex encoding is:
0000000 d8 72 73 74 65 64 0a
0000007
Therefore I converted Ørsted into \xd8rsted
Here's the output when the file and terminal is UTF-8:
The original variable's hex encoding is:
0000000 c3 98 72 73 74 65 64 0a
0000010
Therefore I converted Ørsted into \xc3\x98rsted
In both cases it works as expected.

How do I scan for part of a character?

I’m using bash shell with Mac El Capitan. How can I scan for part of an 8-byte character in a series of files? I got an error when building a project that read
Incorrect string value: '\xF3\x95\x90\x8D\xEA\x93...' for column 'CODE' at row 1
and I’d like to figure out where this string value is coming into play. Unfortunately the error does not give me more information but I know the directory of all the potential files where this could live.
I have corrupted one of my shell files on purpose in the current directory, inserting a 0xf3 char using an hex editor.
I've written this (clumsy) script which uses od (octal dump) in hex mode char-by-char, with hex offset, and greps for the infamous f3 char in the current directory and in all directories below, filtering on files and name (so you can remove the name filtering it still works)
find . -type f -name "*.sh" | while read f
do
line=$(od -Ax -t x1 $f | grep -w f3)
if [ $? = 0 ] ; then
echo file $f is corrupt: $line
fi
done
result on my directory:
file ./quote.sh is corrupt: 000010 69 6d 61 6c f3 3d 24 28 6d 79 73 71 6c 20 2d 75

BASh - Convert list of hex values to binary file (application)

I have a file containing hex representations of code from a small program, and am trying to actually convert it into the program itself.
For example, here is a sample of such text, stored in a file, input.txt:
8d
00
a1
21
53
57
43
48
0e
00
bb
I am using the following BASh snippet to convert the file to a binary file:
rm outfile; while read h; do echo -n ${h}; echo -ne \\x${h} >> outfile; done < input.txt
After opening the output file in VIM:
¡!SWCH»
And then converting it to hex representation via xxd:
0000000: 8d00 a121 5357 4348 0e00 bb0a ...!SWCH....
This is all good, except for one thing: There is a trailing byte, 0a, trailing at the end of my binary output file. This happens for every program file I work with. How is the trailing 0a being appending to every output binary file? It's not present in my input file.
Thank you.
Simply, use xxd directly from a bash like
xxd outfile > outfile.hex
and you will see, here isn't any 0a.
The 0a is appended somewhere when the vim sends a line to xxd command. If you want convert inside vim - try use
vim -b outfile
what open the outfile in binary mode.

What representation is 5761 6920 4D61 6E0D 0A and how to convert to readable form?

I have problem trying to interpret this line:
5761 6920 4D61 6E0D 0A
Is there anyway to interpret this into a human readable text format?
I'm submitting this as a separate answer as I am going to show how I arrived at it without the aid of an online service, and it is generic to any type of data you have a hex representation of.
You can enter the hexadecimal text into a file like so:
0000000: 5761 6920 4d61 6e0d 0a
You can put 8 groups of 4 hex digits on a line that way. Then you can use the xxd program (available on both UNIX-like and Windows systems and can be installed as part of the standard vi editor).
You can then extract the text or data like so:
xxd -r < sample.txt > sample.data
In this case, it yields this on my system:
mbt#redpepper:~$ cat sample.txt
0000000: 5761 6920 4d61 6e0d 0a
mbt#redpepper:~$ cat sample.data
Wai Man
You should be aware of certain types of non-visible characters, too. You can refer to an ASCII table to determine what they are. Furthermore, if you have an ASCII table handy and know that a given source of hex digits is an encoded stream of ASCII bytes, you can do the translation by hand, though it will take a while.
The text is - Wai Man
decoded as
57 61 69 20 4D 61 6E 0D 0A
W a i M a n \r \n
\r - carriage return
\n - new line
Translated using - http://home2.paulschou.net/tools/xlate/

Resources