Membalikkan angka heksadesimal dalam bash

10

Apakah ada perintah sederhana untuk membalikkan angka heksadesimal?

Misalnya, diberi angka heksadesimal:

030201

Outputnya harus:

010203

Menggunakan revperintah, saya mendapatkan yang berikut:

102030

Memperbarui

$ 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
Iñaki Murillo
sumber
2
Tolong jangan tambahkan jawaban untuk pertanyaan Anda.
kucing
@cat Saya menambahkan jawabannya karena yang bekerja untuk saya, ada di komentar dari jawaban yang dipilih. Tapi saya baik-baik saja menghapusnya.
Iñaki Murillo
2
Anda dapat menambahkannya sebagai jawaban dengan mengeklik tombol "Jawab pertanyaan ini" di bawah kotak jawaban (jawaban sendiri disarankan), dan Anda harus, jangan memasukkannya ke dalam pertanyaan.
kucing
2
Pemrogram C dalam diri saya ingin mengatakan "010203" adalah angka oktal, bukan angka hex (0x10203)
dipasang
@infixed Anda tidak salah, tapi saya ingin jawaban yang memperlakukan 010203sebagai heksadesimal, meskipun saya tidak menggunakan 0x
Iñaki Murillo

Jawaban:

10

Anda dapat mengonversinya menjadi biner , membalikkan byte , secara opsional menghapus trailing newlines rev<2.24 , dan mengubahnya kembali:

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

Menggunakan

$ 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

Ini tidak berfungsi jika string berisi byte NUL, karena revakan memotong output pada saat itu.

l0b0
sumber
2
Saya mendapatkan 0102030abukannya010203
Iñaki Murillo
@ l0b0 dan juga saya, dapatkan0102030a
بارپابابا
2
@ IñakiMurillo dalam revversi Anda 2.20.1; gunakan format inixxd -revert -plain <<< '030201' | LC_ALL=C rev | tr -d '\n'| xxd -plain
بارپابابا
2
revsebelum versi 2.24memiliki bug baris baru. info lebih lanjut github.com/karelzak/util-linux/commit/…
بارپابابا
1
Ini tidak berfungsi jika string hex berisi byte '00' NUL.
Sylvain Leroux
10

Jika sistem Anda memiliki revperintah.

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

Jika memiliki tacatau tail -rperintah:

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

Dengan zsh:

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

(seperti dalam ddpendekatan: menukar pasangan karakter, dibagi menjadi daftar karakter individu ( s::), membalik urutan ( Oa) dan bergabung ( j::)).

POSIXly:

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

Atau

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

Dengan perl:

new_hex=$(perl -le 'print reverse(shift =~ /../g)' -- "$hex")
Stéphane Chazelas
sumber
3
Saya akan menyarankan perl -F'(..)' -lane 'print reverse(@F)':)
Sundeep
1
@ Tetap, bagus. Saya tidak tahu orang bisa menggunakan -Fseperti itu. (Saya bisa melihatnya dijelaskan dalam split()manual sekarang).
Stéphane Chazelas
1
sejauh yang saya tahu, -Fpada dasarnya membelah $_.. selain menggunakan regex seperti -F'/"\K\|(?=")/'orang dapat menentukan jumlah split juga ... seperti -F'/:/,$_,2'... gunakan ()jika pemisah harus ditangkap juga
Sundeep
Alih-alih menggunakan pasta, Anda bisa menggunakantr -d '\n'
AKHolland
10

Dengan fold+ tac+ tr:

$ echo 030201|fold -w2|tac|tr -d "\n"
010203
  • fold - belah setiap 2 byte
  • tac - membalikkan kucing
  • tr - hapus baris baru
Ipor Sircer
sumber
4
perl -nE 'say reverse /(..)/g'

Ini mengembalikan setiap baris heksadesimal:

  • /(..)/g membangun daftar dengan korek api yang diambil
Joao
sumber
4

(demi kelengkapan)

$ echo 030201 | grep -o .. | tac | paste -sd '' -
010203
zeppelin
sumber
1
Ini berfungsi jika byte NUL '00' ada di input.
Sylvain Leroux
0

Berdasarkan jawaban Ipor Sircer https://unix.stackexchange.com/a/321867/337458 Saya akan merekomendasikan ini pada Anda ~/.bashrcuntuk memiliki perintah yang bagus yang bisa Anda panggil:

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

$> hex_inverse 030201

010203
mschmoock
sumber