シェルスクリプトでバイナリを16進数と10進数に、またはその逆に変換する必要があるコンテキストがあります。誰かが私にこれのためのツールを提案できますか?
変換を行うのはかなり簡単ですfromバイナリを純粋なbashで(echo
とprintf
は組み込みです):
$ echo "$((2#101010101))"
341
$ printf '%x\n' "$((2#101010101))"
155
Bashだけを使用してバイナリに戻るのは少し複雑なので、その解決策について他の回答を参照することをお勧めします。
バイナリとは、2進数ではなく、0を含むすべての可能なバイト値を持つデータのようなバイナリデータを意味します。
変換するにはfromバイナリ、od
(標準)、xxd
(vim
に付属)またはPerl
の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*",$_)'
次に、変換してtoバイナリ、awk
(標準)、xxd -r
またはPerl
のpack
:
上記のod -tu1
またはPerl
からの10進数出力から:
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*",$_)'
ibase
およびobase
パラメーターを操作することにより、これにbcを使用できます。
トリックは、塩基について明示する必要があるということです。したがって、ibaseが2の場合、バイナリを10にすると2になるため、obaseを10に設定しても何も起こりません。したがって、16進数表記を使用する必要があります。
したがって、2進数から10進数は(obaseがAであることに注意)
2進数から10進数へ:
$> echo 'ibase=2;obase=A;11110001011010'|bc
15450
バイナリから16進数:
$> 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
数値をbase-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
バイナリに変換します。
2進数から16進数への使用:xxdツールはLinuxで、2進数から10進数へは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
前の回答で述べたように、echoとprintfを使用して、Bashで次のようにBinary to DecimalおよびHexa Decimalを実行できます。ここでは、純粋なBashを使用して、10進数と16進数をバイナリに変換する方法を追加しています。
2進数から10進数を使用してエコー
echo "$((2#101010101))"
341
printfを使用した2進数から16進数へ
printf '%x\n' "$((2#101010101))"
155
Bashのみを使用した整数10進数から2進数への変換
Bashのみを使用して、10進数を2進数に変換する場合は、次のように実行できます。
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のみを使用した16進数から2進数への変換
同様に、bashのみを使用して次のように16進数から2進数に:
#!/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
16進数を渡す必要があります。
./hex2bin.bash XyZ
XyZ is not a hexa decimal number bruv!