BASH scripting and bit shifting

Code junkies hangout here

Moderators: ChrisThornett, LXF moderators

BASH scripting and bit shifting

Postby NigelPH » Sun Oct 22, 2006 2:27 pm

I am an occassioal dabbler in this sort of thing when the need arises and being a lapsed SAS programmer I can usually figure things out by tracking stuff down on the web, but this has got me stumped (I used to work with SMF on MVS. so decoding and bit testing using SAS was a doddle).

I have a 256 character hex string, which is the 128 byte EDID string from the attached monitor, the VESA spec states that the Manufacturer 3 character code is contained in 2 bytes, each character is represented by 5 bits of the 16 in those 2 bytes, using the 5 bits as decimal 1=A 2=B 3=C etc.. So using a pencil and scientific calculator I have figured out when I need to do but cannot find any function in BASH to perform them.
My calculations give me...
as Hex = 15c3
as binary = 0001010111000011
so dropping the first bit, then 00101=5=E, 01110=14=N, 00011=3=C, and I get ENC which apparently the code for EIZO.

It is probably not possible in BASH script so may have to look at Perl or similar to do it.

Any comments would be welcome.

Cheers,
Nigel
Last edited by NigelPH on Sun Oct 22, 2006 4:21 pm, edited 1 time in total.
NigelPH
 
Posts: 2
Joined: Sun Oct 22, 2006 11:58 am
Location: London, UK

RE: BASH scripting and bit shifting

Postby nelz » Sun Oct 22, 2006 3:20 pm

You may be able to do this with bc. I've only used it for floating point calculations in Bash scripts, but fro the man page it appears to do far more.
"Insanity: doing the same thing over and over again and expecting different results." (Albert Einstein)
User avatar
nelz
Site admin
 
Posts: 8504
Joined: Mon Apr 04, 2005 11:52 am
Location: Warrington, UK

Postby NigelPH » Sun Oct 22, 2006 8:19 pm

Thanks for that, I had a quick look at BC and then I had an idea, I had notriced the bitwise shifting >> and << that all the pages I visited mentioned they were C like but seldom used.

So by shifting and translating to hex and truncating back to one byte, then shifting again etc..., I managed to figure it out, it went like this (probably a bit long winded)

# 1st 5 bits - just shift the 1st byte shift left 2 bits ( I ignored bit0 )
MFR1=`expr substr $EDIDSTR 17 2`
MFR1=$(printf "%d\n " 0x$MFR1)
MFR1=$(($MFR1 >> 2))
#middle 5 bits - take both bytes, shift right 5 bits, keep the last byte,
# shift left 3 bits, keep the last byte, shift right 3 bits
MFR2=`expr substr $EDIDSTR 17 4`
MFR2=$(printf "%d\n " 0x$MFR2)
MFR2=$(($MFR2 >> 5))
MFR2=$(printf "%X\n " $MFR2)
MFR2L=`expr length $MFR2`
if [ $MFR2L -gt 2 ]
then
MFR2L=$(($MFR2L - 1))
MFR2=`expr substr $MFR2 $MFR2L 2`
fi
MFR2=$(printf "%d\n " 0x$MFR2)
MFR2=$(($MFR2 << 3))
MFR2=$(printf "%X\n " $MFR2)
MFR2L=`expr length $MFR2`
if [ $MFR2L -gt 2 ]
then
MFR2L=$(($MFR2L - 1))
MFR2=`expr substr $MFR2 $MFR2L 2`
fi
MFR2=$(printf "%d\n " 0x$MFR2)
MFR2=$(($MFR2 >> 3))
# last 5 bits - take second byte, shift left 3 bits, keep the last, shift right 3 bits
MFR3=`expr substr $EDIDSTR 19 2`
MFR3=$(printf "%d\n " 0x$MFR3)
MFR3=$(($MFR3 << 3))
MFR3=$(printf "%X\n " $MFR3)
MFR3L=`expr length $MFR3`
if [ $MFR3L -gt 2 ]
then
MFR3L=$(($MFR3L - 1))
MFR3=`expr substr $MFR3 $MFR3L 2`
fi
MFR3=$(printf "%d\n " 0x$MFR3)
MFR3=$(($MFR3 >> 3))
NigelPH
 
Posts: 2
Joined: Sun Oct 22, 2006 11:58 am
Location: London, UK


Return to Programming

Who is online

Users browsing this forum: No registered users and 2 guests