У мене є контекст, в якому мені потрібно перетворити двійкове в шістнадцятковий і десятковий, і на зворотному, у сценарій оболонки. Може хтось запропонує мені інструмент для цього?
У мене є контекст, в якому мені потрібно перетворити двійкове в шістнадцятковий і десятковий, і на зворотному, у сценарій оболонки. Може хтось запропонує мені інструмент для цього?
Відповіді:
Перетворення з бінарного в чистий баш ( echo
і printf
є вбудованими) досить просто:
$ echo "$((2#101010101))"
341
$ printf '%x\n' "$((2#101010101))"
155
Повернутися до бінарного, використовуючи лише bash, є дещо складнішим, тому я пропоную вам побачити інші відповіді для вирішення цього питання.
printf '%x\n' 10
, наприклад.
printf %d
для bin2dec? $(( ... ))
вже дає десятковий результат, echo
достатньо.
printf '%s\n' foo
замість echo
різних причин (в основному портативності), з тієї ж причини, я не використовую це тут.
echo
вбудований). Моє ліжко!
Якщо припустити, що під двійковим, ви маєте на увазі двійкові дані як у даних з будь-яким можливим значенням байта, включаючи 0, а не базові 2 числа:
Для перетворення з виконуваного файлу, od
(стандарт), xxd
(поставляється з vim
) або perl
«s unpack
приходить на розум.
od -An -vtu1 # for decimal
od -An -vtx1 # for hexadecimal
xxd -p # for hexa
perl -pe 'BEGIN{$\="\n";$/=\30};$_=unpack("H*",$_)' # like xxd -p
# for decimal:
perl -ne 'BEGIN{$\="\n";$/=\30;$,=" "}; print unpack("C*",$_)'
Тепер, щоб перетворити назад у двійкові, awk
(стандартні) xxd -r
або perl
's pack
:
Від десяткового виходу зверху od -tu1
чи perl
вище:
LC_ALL=C awk '{for (i = 1; i <= NF; i++) printf "%c", $i}'
perl -ape '$_=pack("C*",@F)'
Від гекса perl
або xxd -p
вище:
xxd -r -p
perl -pe 'chomp;$_=pack("H*",$_)'
Ви можете використовувати bc для цього, маніпулюючи параметрами ibase
та obase
:
Хитрість полягає в тому, що вам потрібно чітко пояснювати основи. Отже, якщо ваш ibase дорівнює 2, то якщо ви встановите obase на 10, він нічого не зробить, оскільки 10 у двійковій системі - це 2. Отже, вам потрібно використовувати шістнадцяткову нотацію.
Тож двійкові до десяткових були б (дивіться, що обасе є A)
Двійкові до десяткових:
$> echo 'ibase=2;obase=A;11110001011010'|bc
15450
Двійкові до шестигранних:
$> echo 'ibase=2;obase=10000;11110001011010'|bc
3C5A
Якщо obase
спочатку змінити 'вихідну базу' , це має бути легше:
$> echo 'obase=10;ibase=2;11110001011010'|bc
15450
$> echo 'obase=16;ibase=2;11110001011010'|bc
3C5A
echo 'ibase=2;obase=F;1111
яка повинна дорівнювати десятковій 15, тобто. F в шістнадцятковій. Виходить як 10, що знаходиться в базі 15 (цифри 0-E). Крім того , легше , якщо ви вказати obase першої , наприклад: echo 'obase=16;ibase=2;1111'|bc
. Без плутанини.
ibase
, ви навіть повинні забезпечити введення в цій базі obase
. Так у вашому прикладі було б echo 'ibase=2;obase=10000;11110001011010'|bc
. Краще прислухайтеся до порад золотокрилих і скасуйте порядок - спочатку встановіть obase
, потім ibase
.
Якщо ви маєте на увазі перетворення чисел з базової-2 в 10 або 16 і назад, bc
це стандартний інструмент для цього, як це вже згадувало psarossy .
decimal=123
binary=$(echo "obase=2;$decimal" | bc)
hex=$(echo "obase=16;ibase=2;$binary" | bc)
Деякі оболонки, як, наприклад, zsh
мають вбудовану підтримку перетворення бази в рамках своїх операторів арифметичного розширення:
decimal=123
binary=$(([##2]decimal))
hex=$(([##16]decimal))
hex=$(([##16]2#$binary))
decimal=$((2#$binary))
і так далі.
І те, ksh93
і zsh
також підтримують:
typeset -i2 binary=123
typeset -i16 dec2hex=123 bin2hex='2#1111'
Але зауважте, що при розширенні $binary
буде встановлений 2#
або 16#
префікс (який ви можете зняти ${binary#*#}
.
ksh93
також підтримує:
printf "%..2d\n" 123
перетворити на бінарне.
Для двійкового та шістнадцяткового використання: інструмент xxd у Linux та для двійкових до десяткових можна використовувати інструмент qalculate.
Довідка щодо типу xxd xxd --help
або man xxd
в Linux.
Ви можете використовувати PHP:
$ php -r 'printf("%b", 11);'
1011
Або Perl:
$ perl -e 'print unpack("B*", pack("c", 11))'
00001011
$ perl -e 'print unpack("B*", pack("C", 11))'
00001011
$ perl -e 'print unpack("B*", pack("W", 11))'
00001011
$ perl -e 'print unpack("B*", pack("n", 11))'
0000000000001011
$ perl -e 'print unpack("B*", pack("N", 11))'
00000000000000000000000000001011
Або POSIX Awk svnpenn / stdlib :
$ awklib 'BEGIN {print mt_basecon(1011, 2, 16)}'
B
$ awklib 'BEGIN {print mt_basecon(1011, 2, 10)}'
11
$ awklib 'BEGIN {print mt_basecon("B", 16, 2)}'
1011
$ awklib 'BEGIN {print mt_basecon(11, 10, 2)}'
1011
Як було сказано в попередній відповіді, ви можете зробити Binary to Decimal і Hexa Decimal, як показано нижче в Bash, використовуючи echo і printf. Я просто додаю тут, як перетворити з десяткової та шістнадцяткової в бінарну, використовуючи чистий Bash.
Двійкові до десяткової за допомогою відлуння
echo "$((2#101010101))"
341
Двійкові до шестидесяткових за допомогою printf
printf '%x\n' "$((2#101010101))"
155
Ціле число в двійкове перетворення з використанням лише Bash
Використовуючи лише Bash, якщо ви хочете перетворити десятковий у двійковий, ви можете це зробити так:
touch dec2bin && chmod +x "$_" && vim "$_"
А потім скопіюйте та вставте наступне:
#!/bin/bash
## converting decimal integer to binary, pass int as a parameter
num=$1;
dec2bin()
{ [ "$num" == "" ] && { printf "Error: Pass an integer\n"; exit 1; };
op=2; ## Since we're converting to binary
quo=$(( $num / $op)); rem=$(( $num % $op)); ## quotient and remainder
remarray=(); ## array for putting remainder inside array
remarray+=("$rem"); ## array expansion
until [[ $quo -eq 0 ]]; do
num=$quo; quo=$(( $num / $op)); ## looping to get all remainder untill 0
rem=$(( $num % $op)); remarray+="$rem"; ## array expansion
done
binary=$(echo "${remarray[@]}" | rev); ## reversing array
printf "$binary\n"; ## printing reversed array
}
main()
{ [[ -n ${num//[0-9]/} ]] &&
{ printf "Error: $num is not an integer bruv!\n"; return 1;
} || { dec2bin $num; }
}
main;
А потім спробуйте звідки ви зберегли:
./dec2bin 420
110100100
Ціле число потрібно додати !!
./dec2bin 420.py
420.py is not an integer bruv!
Шестнадцятковий до бінарного перетворення, використовуючи лише Bash
Аналогічно, шістнадцятковий до двійкового, як слід, використовуючи лише bash:
#!/usr/local/bin/bash
## converting hexadecimal to binary, pass hex as a parameter
hex=$1;
hex2bin()
{ [ "$hex" == "" ] && { printf "Error: Pass a hex\n"; exit 1; };
op=2; num=$((16#$hex)); ## converting hex to integer
quo=$(( $num/ $op)); rem=$(( $num% $op)); ## quotient and remainder
remarray=(); remarray+=("$rem"); ## array expansion
until [[ $quo -eq 0 ]]; do
num=$quo; quo=$(( $num / $op)); ## looping to get all remainder untill 0
rem=$(( $num % $op)); remarray+="$rem"; ## array expansion
done
binary=$(echo "${remarray[@]}" | rev); ## reversing array
printf "$binary\n"; ## printing reversed array
}
main()
{
[[ -n ${hex//[0-9,A-F,a-f]/} ]] &&
{ printf "Error: $hex is not a hex bruv!\n"; return 1;
} || { hex2bin $hex; }
}
main;
Наприклад:
./hex2bin 1aF
110101111
Шістнадцятковий повинен бути переданий:
./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!