Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

need a shell script to convert big endian to little endian

I need a shell script program to print the hexadecimal number from big endian to little endian

For example

  • Input: my virtual address = 00d66d7e
  • Output: 7e6dd600

How can I can I create this in a bash script?

like image 474
Rajiv Avatar asked Mar 10 '14 09:03

Rajiv


3 Answers

Just had to do this... but from decimal to little endian.. adapting that here:

echo 00d66d7e | tac -rs .. | echo "$(tr -d '\n')"

achieves the desired result, for arbitrarily sized hexadecimal representations of unsigned integers.

(h/t 'tac -rs' MestreLion, very nice!)

like image 193
Brian Chrisman Avatar answered Nov 12 '22 06:11

Brian Chrisman


In response to Freewind's comment request and building off of hutheano's great answer, I wrote my own bash script and I include a condensed version below. The full script can be downloaded here.

The following implementation accounts for odd length strings, 0x or \x prefixes, and multiple output formats and can be used like the following:

$ be2le d76f411475428afc90947ee320 0xaaff 0xffa '\x3'
20e37e9490fc8a427514416fd7
0xffaa
0xfa0f
\x03

be2le bash script

#!/bin/bash

args=()

format=preserve
delimiter="\n"
nonewline=false
join=false
strip=false

while (( "$#" )); do
    case "$1" in
        -h|--help) usage;;
        -f) format=$2; shift 2;;
        --format=*) format="${1#*=}"; shift;;
        -d) delimiter=$2; shift 2;;
        --delimiter=*) delimiter="${1#*=}"; shift;;
        -n|--no-newline) nonewline=true; shift;;
        -j|--join) join=true; shift;;
        -s|--strip-null) strip=true; shift;;
        -*|--*) echo "Error: unsupported flag $1 specified"; exit 1;;
        *) args=( "${args[@]}" "$1" ); shift;;
    esac
done

case "$format" in
    preserve);;
    int) prefix="0x";;
    char) prefix="\x";; 
    raw) ;;
    *) echo "Error: unsupported format $format"; exit 1;;
esac

n=0
parts=()
for arg in ${args[@]}; do

    digest=""
    prefix=""

    # remove prefix if string begins with "0x"
    if [[ $arg =~ ^[0\\]x ]]; then
        if [ "$format" == "preserve" ]; then
            prefix=${arg:0:2}
        fi
        arg=${arg:2}
    fi

    # zero-pad if string has odd length
    if [ $[${#arg} % 2] != 0 ]; then
        arg="0$arg"
    fi

    part=""
    i=${#arg}
    while [ $i -gt 0 ]; do
        i=$[$i-2]
        byte=${arg:$i:2}
        if [ $strip == true ] && [ -z "$part" ] && [ $byte == "00" ]; then
            continue
        fi
        case "$format" in
            int) part="$part"'0x'"$byte ";;
            char) part="$part\x$byte";;
            raw) part="$part$(printf "%b" "\x$byte")";;
            *) part="$part$byte";;
        esac
    done

    digest="$prefix$digest$part"

    parts=( "${parts[@]}" "$digest" )
    n=$[$n+1]

done

if [ $join == true ]; then
    case "$format" in
        *) printf "%s" "${parts[@]}";;
    esac
else
    i=0
    for part in "${parts[@]}"; do
        if [[ $(($i + 1)) < $n ]]; then
            printf "%s$delimiter" "$part"
        else
            printf "%s" "$part"
        fi
        i=$(($i+1))
    done
fi

if [ $nonewline == false ]; then
    echo
fi
like image 40
NoodleOfDeath Avatar answered Nov 12 '22 07:11

NoodleOfDeath


For 32 bit addresses, assuming it's zero padded:

v=00d66d7e 
echo ${v:6:2}${v:4:2}${v:2:2}${v:0:2}
# 7e6dd600
like image 39
Karoly Horvath Avatar answered Nov 12 '22 07:11

Karoly Horvath