i have hex value


when i change it to binary i got

1011 0100 0101 0101

i want to swap the bits with a rule of :

origin bits index : 0123456789ABCDEF
result bits index : D5679123C4EF80AB`

then i have result

1100 1011 0001 1101

to hex is


can you help to get script shell do this ?

thanks in advance.

  • 3
    So B becomes F looking at your origin/result index. How does it become C in your desired answer ? – steve Mar 3 '17 at 16:16
  • A shell script may not be the best tool for this. Maybe a Perl script or a short C program? – Kusalananda Mar 3 '17 at 16:28

As noted, the shell is probably not the best place to do this. If you really want to, here's a solution using awk, dc, printf, sed, and tr:

# file: swap-bits

indices() {
    printf '%s\n' "$1"         \
    | sed 's/./\0 1+p\n/g'     \
    | sed '1s/^/10o16i/'       \
    | dc                       \
    | sed 's/^/substr( $0, /'  \
    | sed 's/$/, 1 )/'         \
    | tr '\n' ' '

sed 's/^/2o16iF/'                                              \
| sed 's/$/p/'                                                 \
| dc                                                           \
| sed 's/....//'                                               \
| awk "{ print \"16o2i\" $(indices ${target_order}) \"pq\" }"  \
| dc                                                           \
| sed 's/^/0000/'                                              \
| sed 's/.*\(....\)$/\1/'

This does no checking of the input. The target_order variable should be set to the preferred permutation of your 16 bits.

The function indices takes as input such a string, and outputs a sequence of substr( $0, n, 1 ) commands, which awk will use to permute its input.

The main body of the script begins by using dc to convert the input from hexadecimal to binary. Leading zero-bits are preserved by prefixing the input with F and discarding the four one-bits. The result is fed to awk, which prints a command that tells dc to convert from binary to hexadecimal, then the permuted output, then a command that tells dc to print and quit. This is of course fed into dc. Finally, sed is used again to ensure leading zeroes exist in the output if appropriate.

Input comes on stdin, output on stdout, like so:

$ echo B455 | ./swap-bits
perl -wMstrict -le '
   my @bits = unpack "(A1)16", sprintf "%016b", hex shift;
   my $bitmap = "D5679123C4EF80AB";
   @bits = @bits[ map { hex } split //, $bitmap ];
   print sprintf "%04X", oct "0b@bits";
' "B455"

Result: CB15


First we convert the input hex number into it's 16-bit binary equivalent and store the indi-
dual bits in the array @bits. The individual bits are now mapped according to the bitmap wh-
ich is generated by splitting into single bits and getting their decimal equivalents which
are the array indices of @bits. Last step involves in converting the mapped bits into their
4-digit hex counterpart.

protected by Community Mar 3 '17 at 23:43

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.