Inverser un nombre hexadécimal en bash


10

Existe-t-il une commande simple pour inverser un nombre hexadécimal?

Par exemple, étant donné le nombre hexadécimal:

030201

La sortie doit être:

010203

En utilisant la revcommande, j'obtiens ce qui suit:

102030

Mise à jour

$ 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

2
Veuillez ne pas ajouter la réponse à votre question.
chat

@cat J'ai ajouté la réponse car celle qui a fonctionné pour moi, se trouve dans les commentaires de la réponse sélectionnée. Mais je vais bien le retirer.
Iñaki Murillo

2
Vous pouvez l'ajouter comme réponse en cliquant sur le bouton «Répondre à cette question» sous la boîte de réponse (les réponses personnelles sont encouragées), et vous devriez, ne le mettez pas dans la question.
chat

2
Le programmeur C en moi veut dire "010203" est un nombre octal, pas un nombre hexadécimal (0x10203)
infixé

@infixed Vous ne vous trompez pas, mais je voulais une réponse qui traite 010203comme un hexadécimal, même si je n'utilise pas 0x
Iñaki Murillo

Réponses:


10

Vous pouvez le convertir en binaire , inverser les octets , supprimerrev éventuellement les sauts de ligne <2.24 et le reconvertir:

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

En utilisant

$ 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

Cela ne fonctionne pas si la chaîne contient l'octet NUL, car revtronquera la sortie à ce point.


2
Je reçois à la 0102030aplace de010203
Iñaki Murillo

@ l0b0 et moi aussi, obtenez0102030a
بارپابابا

2
@ IñakiMurillo dans votre revversion 2.20.1; utilisez ce formatexxd -revert -plain <<< '030201' | LC_ALL=C rev | tr -d '\n'| xxd -plain
بارپابابا

2
revavant la version 2.24ont un nouveau bug de ligne. plus d'infos github.com/karelzak/util-linux/commit/…
بارپابابا

1
Cela ne fonctionne pas si la chaîne hexadécimale contient l'octet NUL '00'.
Sylvain Leroux

10

Si votre système a une revcommande.

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

S'il a une commande tacou tail -r:

new_hex=$(echo "$hex" | fold -w 2 | tac | paste -sd '\0' -)

Avec zsh:

setopt extendedglob
new_hex=${(j::)${(s::Oa)${hex//(#b)(?)(?)/$match[2]$match[1]}}}

(comme dans l' ddapproche: permuter des paires de caractères, diviser en liste de caractères individuels ( s::), inverser l'ordre ( Oa) et joindre ( j::)).

POSIX:

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"
)

Ou

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

Avec perl:

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

3
J'allais suggérer perl -F'(..)' -lane 'print reverse(@F)':)
Sundeep

1
@Sundeep, nice. Je ne savais pas qu'on pouvait utiliser -Fcomme ça. (Je peux le voir décrit dans le split()manuel maintenant).
Stéphane Chazelas

1
pour autant que je sache, -Fse divise fondamentalement $_.. à part l'utilisation d'expressions régulières comme -F'/"\K\|(?=")/'on peut également spécifier le nombre de divisions ... comme -F'/:/,$_,2'... utiliser ()si le séparateur doit également être capturé
Sundeep

Au lieu d'utiliser de la pâte, vous pourriez utilisertr -d '\n'
AKHolland

10

Avec fold+ tac+ tr:

$ echo 030201|fold -w2|tac|tr -d "\n"
010203
  • fold - fractionné tous les 2 octets
  • tac - chat inversé
  • tr - supprimer les nouvelles lignes

4
perl -nE 'say reverse /(..)/g'

Cela annule chaque ligne hexadécimale:

  • /(..)/g construit une liste avec les matchs capturés

4

(par souci d'exhaustivité)

$ echo 030201 | grep -o .. | tac | paste -sd '' -
010203

1
Cela fonctionne si l'octet NUL '00' est en entrée.
Sylvain Leroux

0

Sur la base de la réponse d'Ipor Sircer https://unix.stackexchange.com/a/321867/337458, je recommanderais ceci dans votre ~/.bashrcpour avoir une belle commande que vous pouvez simplement appeler:

function hex_inverse() {
    echo ${1} | fold -w2 | tac | tr -d "\n" ; echo "" 
}

$> hex_inverse 030201

010203
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.