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/.*\(....\)$//'