trocar posição de bits no linux

1

eu tenho valor hexadecimal

B455

quando eu mudo para binário eu tenho

1011 0100 0101 0101

eu quero trocar os bits com uma regra de:

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

então eu tenho resultado

1100 1011 0001 1101

para hex é

CB1D

você pode ajudar a fazer o script shell fazer isso?

obrigado antecipadamente.

    
por user219018 03.03.2017 / 17:10

2 respostas

1

Como observado, o shell provavelmente não é o melhor lugar para fazer isso. Se você realmente quiser, aqui está uma solução usando awk , dc , printf , sed e tr :

#!/bin/sh
# file: swap-bits

target_order='D5679123C4EF80AB'
indices() {
    printf '%s\n' "$1"         \
    | sed 's/./
$ echo B455 | ./swap-bits
CB15
1+p\n/g' \ | sed '1s/^/10o16i/' \ | dc \ | sed 's/^/substr( $0, /' \ | sed 's/$/, 1 )/' \ | tr '\n' ' ' echo } sed 's/^/2o16iF/' \ | sed 's/$/p/' \ | dc \ | sed 's/....//' \ | awk "{ print \"16o2i\" $(indices ${target_order}) \"pq\" }" \ | dc \ | sed 's/^/0000/' \ | sed 's/.*\(....\)$//'

Isso não faz verificação da entrada. A variável target_order deve ser configurada para a permutação preferencial dos seus 16 bits.

A função indices toma como entrada uma string e produz uma seqüência de comandos substr( $0, n, 1 ) , que awk usará para permutar sua entrada.

O corpo principal do script começa usando dc para converter a entrada de hexadecimal em binário. Os bits zero principais são preservados prefixando a entrada com F e descartando os quatro bits. O resultado é alimentado para awk , que imprime um comando que informa dc para converter de binário para hexadecimal, depois a saída permutada e, em seguida, um comando que diz dc para imprimir e sair. Isto é claro alimentado em dc . Finalmente, sed é usado novamente para garantir zeros à esquerda, se apropriado.

A entrada vem em stdin , saída em stdout , assim:

#!/bin/sh
# file: swap-bits

target_order='D5679123C4EF80AB'
indices() {
    printf '%s\n' "$1"         \
    | sed 's/./
$ echo B455 | ./swap-bits
CB15
1+p\n/g' \ | sed '1s/^/10o16i/' \ | dc \ | sed 's/^/substr( $0, /' \ | sed 's/$/, 1 )/' \ | tr '\n' ' ' echo } sed 's/^/2o16iF/' \ | sed 's/$/p/' \ | dc \ | sed 's/....//' \ | awk "{ print \"16o2i\" $(indices ${target_order}) \"pq\" }" \ | dc \ | sed 's/^/0000/' \ | sed 's/.*\(....\)$//'
    
por 03.03.2017 / 19:17
0
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

Resumo:

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.
    
por 04.03.2017 / 08:06