BASH conversão de base de decimal para hex

20

No Bash, como é feita a conversão de base do decimal para outra base, especialmente hexadecimal. Parece fácil ir para o outro lado:

$ echo $((16#55))
85

Com uma pesquisa na web, eu encontrei um script que faz a matemática e manipulação de caracteres para fazer a conversão, e eu poderia usar isso como uma função, mas eu pensei que bash já teria uma base embutida conversão - não é?

    
por Dave Rove 19.03.2015 / 14:19

4 respostas

29

Com bash (ou qualquer shell, desde que o comando printf esteja disponível (um comando POSIX padrão geralmente construído nos shells)):

printf '%x\n' 85

Com zsh , você também pode fazer:

dec=85
hex=$(([##16]dec))

Isso funciona para bases de 2 a 36 (com 0-9a-z insensível a dígitos).

Com ksh93 , você pode usar:

dec=85
base54=$(printf %..54 "$dec")

Que funciona para bases de 2 a 64 (com 0-9a-zA-Z@_ como os dígitos).

Com ksh e zsh , também há:

$ typeset -i34 x=123; echo "$x"
34#3l

Embora isso esteja limitado a até 36 em ksh88, zsh e pdksh e 64 em ksh93.

Observe que todos esses são limitados ao tamanho dos long inteiros em seu sistema ( int com alguns shells). Para algo maior, você pode usar bc ou dc .

$ echo 'obase=16; 9999999999999999999999' | bc
21E19E0C9BAB23FFFFF
$ echo '16o 9999999999999999999999 p' | dc
21E19E0C9BAB23FFFFF

Com bases suportadas variando de 2 a algum número requerido pelo POSIX para ser pelo menos tão alto quanto 99. Para bases maiores que 16, dígitos maiores que 9 são representados como números decimais com 0 números separados por espaço.

$ echo 'obase=30; 123456' | bc
 04 17 05 06
    
por 19.03.2015 / 14:30
5

Use printf:

$ printf "%d %x\n" $((16#55)) $((10#85))
85 55

Para atribuir o valor a uma variável, use a substituição de comando:

$ x=$( printf "%x" 85 ) ; echo $x
55
    
por 19.03.2015 / 14:33
1

Use a substituição de Expansão Aritmética integrada presente em todos os shells compatíveis com POSIX - o que é praticamente universal atualmente.

$ echo $((0xbc))
188

e

$ hex=dead
$ dec=$((0x$hex))
$ echo $dec
57005

CUIDADO: Particularmente no último exemplo, a expansão pode causar resultados inesperados - os dígitos hexadecimais na variável 'hex' precisam formar uma constante hexadecimal legal, caso contrário, mensagens de erro potencialmente obscuras acontecem. por exemplo. se 'hex' fosse '0xdead', a expansão aritmética seria 0x0xdead, o que não é interpretável como uma constante. Claro que, nesse caso, a expansão aritmética $ (($ hex)) faria o truque. É deixado como um exercício para o leitor criar a correspondência de padrão de processamento de substring simples que removeria um prefixo '0x' opcional.

    
por 30.12.2015 / 00:42
0

Você pode usar a biblioteca de Velud do awk:

$ velour -n 'print n_baseconv(15, 10, 16)'
F

Ou:

$ velour -n 'print n_baseconv(ARGV[1], 10, 16)' 15
F
    
por 27.03.2017 / 01:12