Comment convertir un nombre décimal en binaire en Bash ?
Pour convertir un nombre décimal en binaire, en Bash, suivez ce tweet : https://twitter.com/climagic/status/593842202314420224.
Et voici la conversion du décimal 27 en son équivalent binaire :
$ Dec2Bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1});echo ${Dec2Bin[27]}
00011011
Alors, comment ça marche ?
Pour commencer, voici comment faire un tableau en bash, qui va contenir les 3
chaînes foo
, bar
, et baz
. Ne soyez pas surpris par le manque de guillemets
autour des chaînes, Bash est fait pour traiter du texte.
$ myarray=(foo bar baz)
Et voici comment afficher le contenu de ce tableau.
$ echo ${myarray[@]}
foo bar baz
On peut bien sûr accéder aux éléments du tableau séparément :
$ echo ${myarray[0]}
foo
$ echo ${myarray[1]}
bar
$ echo ${myarray[2]}
baz
Pour connaître la taille d’un tableau, voici la syntaxe :
$ echo ${#myarray[@]}
3
Appliquons ce nouveau savoir au tableau Dec2Bin
, qui contient…
…
…des trucs :
$ Dec2Bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
Combien a-t-il d’éléments ?
$ echo ${#Dec2Bin[@]}
256
256 ? Et ça ressemble à quoi ?
$ echo ${Dec2Bin[@]}
00000000 00000001 00000010 00000011 00000100 00000101 00000110 00000111 00001000
00001001 00001010 00001011 00001100 00001101 00001110 00001111 00010000 00010001
...
11101010 11101011 11101100 11101101 11101110 11101111 11110000 11110001 11110010
11110011 11110100 11110101 11110110 11110111 11111000 11111001 11111010 11111011
11111100 11111101 11111110 11111111
Tranquille, Dec2Bin
est un tableau qui contient 256 chaînes représentant les
nombres binaires de 0 à 255.
Les crochets {}
créent un range :
$ echo {0..1}
0 1
$ echo {a..f}
a b c d e f
Plusieurs crochets {}
les uns à la suite des autres produisent toutes les
permutations possibles :
$ echo {0..1}{0..1}
00 01 10 11
Et on peut mettre tout ça dans un tableau :
$ a=({0..1})
$ echo ${a[@]}
0 1
$ a=({0..1}{0..1})
$ echo ${a[@]}
00 01 10 11
$ a=({0..1}{0..1}{0..1})
$ echo ${a[@]}
000 001 010 011 100 101 110 111
Et voilà, il faut encore savoir qu’ici, le point-virgule sert à joindre 2 lignes de code en une seule :
$ Dec2Bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
$ echo ${Dec2Bin[27]}
00011011
Bonus 1 - Le même en hexadécimal
Et si on voulait convertir un nombre décimal en hexadécimal plutôt qu’en
binaire ? Il faudrait générer toutes les permutations entre deux suites
0 1 2 3 4 5 6 7 8 9 A B C D E F
:
{% highlight bash %} $ echo {{0..9},{A..F}}{{0..9},{A..F}} 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF {% endhighlight %}
{% highlight bash %} $ Dec2Hex=({{0..9},{A..F}}{{0..9},{A..F}});echo ${Dec2Hex[27]} 1B {% endhighlight %}
Bonus 2 - Le même en Ruby
On peut faire la même chose en Ruby en utilisant repeated_permutation
:
>> [0,1].repeated_permutation(8).to_a.each{|e| puts e.join}
00000000
00000001
00000010
00000011
00000100
00000101
...
11111010
11111011
11111100
11111101
11111110
11111111
Il peut-être intéressant de comparer les deux versions :
$ ruby -e "puts [0,1].repeated_permutation(8).to_a[27].join"
00011011
$ Dec2Bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1});echo ${Dec2Bin[27]}
00011011
Bonus 3 - Encore plus court
Pour finir, on peut faire plus court avec Bash en utilisant {0,1}
au lieu de
{0..1}
puisqu’il y a seulement deux éléments :
$ Dec2Bin=({0,1}{0,1}{0,1}{0,1}{0,1}{0,1}{0,1}{0,1});echo ${Dec2Bin[27]}
00011011