Reverte um número hexadecimal no bash

8

Existe um comando simples para inverter um número hexadecimal?

Por exemplo, dado o número hexadecimal:

030201

A saída deve ser:

010203

Usando o comando rev , recebo o seguinte:

102030

Atualizar

$ bash --version | head -n1
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
$ xxd -version
xxd V1.10 27oct98 by Juergen Weigert
$ rev --version
rev from util-linux 2.20.1
    
por Iñaki Murillo 08.11.2016 / 13:34

5 respostas

10

Você pode convertê-lo em binário , inverta os bytes , opcionalmente remova as novas linhas finais rev < 2.24 e converta de volta:

$ xxd -revert -plain <<< 030201 | LC_ALL=C rev | tr -d '\n' | xxd -plain
010203

Usando

$ bash --version | head -n1
GNU bash, version 4.3.42(1)-release (x86_64-redhat-linux-gnu)
$ xxd -version
xxd V1.10 27oct98 by Juergen Weigert
$ rev --version
rev from util-linux 2.28.2

Isso não funciona se a string contiver o byte NUL, porque rev truncará a saída nesse ponto.

    
por 08.11.2016 / 13:37
10

Se o seu sistema tiver um comando rev .

hex=030201
new_hex=$(printf %s "$hex" | dd conv=swab 2> /dev/null | rev)

Se tiver um comando tac ou tail -r :

new_hex=$(echo "$hex" | fold -w 2 | tac | paste -sd '
setopt extendedglob
new_hex=${(j::)${(s::Oa)${hex//(#b)(?)(?)/$match[2]$match[1]}}}
' -)

com zsh :

new_hex=$(
  awk '
    BEGIN {
      hex = ARGV[1]; l = length(hex)
      for (i = 1; i < l; i += 2)
        new_hex = substr(hex, i, 2) new_hex
      print new_hex
    }' "$hex"
)

(como na abordagem dd : trocar pares de caracteres, dividir em lista de caracteres individuais ( s:: ), inverter a ordem ( Oa ) e unir ( j:: )).

POSIXly:

new_hex=$(echo "$hex" |
  sed -e 'G;:1' -e 's/\(..\)\(.*\n\)//;t1' -e 's/.//')

Ou

new_hex=$(perl -le 'print reverse(shift =~ /../g)' -- "$hex")

com perl :

hex=030201
new_hex=$(printf %s "$hex" | dd conv=swab 2> /dev/null | rev)
    
por 08.11.2016 / 13:57
8

Com fold + tac + tr :

$ echo 030201|fold -w2|tac|tr -d "\n"
010203
  • fold - dividir a cada 2 bytes
  • tac - reverse cat
  • tr - remover novas linhas
por 08.11.2016 / 14:03
4
perl -nE 'say reverse /(..)/g'

Isso reverte cada linha hexadecimal:

  • /(..)/g constrói uma lista com as correspondências capturadas
por 08.11.2016 / 16:52
4

(por questão de integridade)

$ echo 030201 | grep -o .. | tac | paste -sd '' -
010203
    
por 08.11.2016 / 17:25