IP アドレス: 66.102.13.19 があり、このアドレスからこのアドレスを受け取った
http://1113984275
しかし、どのように?そして、bashの助けを借りてこれを作成する方法. 例えば、このサービスならできるのですが、アルゴリズムがわかりません。
ip=66.102.13.19
IFS=. read -r a b c d <<< "$ip"
printf '%s%d\n' "http://" "$((a * 256 ** 3 + b * 256 ** 2 + c * 256 + d))"
ところで、あなたの質問の番号は IP アドレスと一致しません。
10 進数を IP に変換するには:
#!/bin/bash
dec2ip () {
local ip dec=$@
for e in {3..0}
do
((octet = dec / (256 ** e) ))
((dec -= octet * 256 ** e))
ip+=$delim$octet
delim=.
done
printf '%s\n' "$ip"
}
dec2ip "$@"
IP を 10 進数に変換するには:
#!/bin/bash
ip2dec () {
local a b c d ip=$@
IFS=. read -r a b c d <<< "$ip"
printf '%d\n' "$((a * 256 ** 3 + b * 256 ** 2 + c * 256 + d))"
}
ip2dec "$@"
デモ:
$ ./dec2ip 1113984275
66.102.13.19
$ ./ip2dec 66.102.13.19
1113984275
これら 2 つのスクリプトは、一部の Bourne 派生シェルには存在しない Bash の機能に依存しています。代わりに使用する AWK バージョンを次に示します。
#!/usr/bin/awk -f
# dec2ip
BEGIN {
dec = ARGV[1]
for (e = 3; e >= 0; e--) {
octet = int(dec / (256 ^ e))
dec -= octet * 256 ^ e
ip = ip delim octet
delim = "."
}
printf("%s\n", ip)
}
と
#!/usr/bin/awk -f
# ip2dec
BEGIN {
ip = ARGV[1]
split(ip, octets, ".")
for (i = 1; i <= 4; i++) {
dec += octets[i] * 256 ** (4 - i)
}
printf("%i\n", dec)
}
これらは、上記の Bash スクリプトと同じ方法で呼び出すことができます。
バイナリ シフトは、乗算または除算より常に高速です。
バイナリ AND を使用すると、mod よりも高速です。
ip2dec(){ # Convert an IPv4 IP number to its decimal equivalent.
declare -i a b c d;
IFS=. read a b c d <<<"$*";
echo "$(((a<<24)+(b<<16)+(c<<8)+d))";
}
dec2ip(){ # Convert an IPv4 decimal IP value to an IPv4 IP.
declare -i a=$((0xff)) b=$1;
c="$((b>>24&a)).$((b>>16&a)).$((b>>8&a)).$((b&a))";
echo "$c";
}
ip=66.102.13.19
a=$(ip2dec "$ip")
b=$(dec2ip "$a")
echo "$ip DecIP=$a IPv4=$b "
注: このシステムは のような値で失敗します0008
。
Bash はそれを 8 進数と見なします。
これを解決するには、次のような方法で各値をクリーンアップする必要があります。
IsDecInt()( # Is the value given on $1 a decimal integer (with sign)?
declare n=$1; set --
if [[ $n =~ ^([+-]?)((0)|0*([0-9]*))$ ]]; then
set -- "${BASH_REMATCH[@]:1}"
else
exit 1
fi
echo "$1$3$4";
)
a=$(IsDecInt "$a")||{ Echo "Value $a is not an integer" >&2; exit 1; }
(非常に)古いシェルの場合:2.04以降のbash、またはダッシュまたは任意の(合理的な)シェル:
ip2dec(){ # Convert an IPv4 IP number to its decimal equivalent.
local a b c d;
IFS=. read a b c d <<-_EOF_
$1
_EOF_
echo "$(((a<<24)+(b<<16)+(c<<8)+d))";
}
dec2ip(){ # Convert an IPv4 decimal IP value to an IPv4 IP.
local a=$((~(-1<<8))) b=$1;
c="$((b>>24&a)).$((b>>16&a)).$((b>>8&a)).$((b&a))";
echo "$c";
}
ip=$1
a=$(ip2dec "$ip")
b=$(dec2ip "$a")
echo "$ip DecIP=$a IPv4=$b "
int から ip への変換用の私のバージョン:
echo 3232235521| awk {'print rshift(and($1, 0xFF000000), 24) "." rshift(and($1, 0x00FF0000), 16) "." rshift(and($1, 0x0000FF00), 8) "." and($1, 0x000000FF) '}
これが私の見解です:
$ host google.com
google.com has address 216.58.216.142
$ ./ip2d.sh 216.58.216.142
3627735182
$ ./d2ip.sh 3627735182
216.58.216.142
ip2d.sh:
#!/bin/bash
IFS=.
set -- $*
echo $(( ($1*256**3) + ($2*256**2) + ($3*256) + ($4) ))
d2ip.sh:
#!/bin/bash
IFS=" " read -r a b c d <<< $(echo "obase=256 ; $1" |bc)
echo ${a#0}.${b#0}.${c#0}.${d#0}
固定オフセットなどへの参照なしで任意の数のオクテットも処理する、より簡単なソリューションがあると思います。
echo 66.102.13.19 |
tr . '\n' |
while read octet; do
printf "%.08d" $(echo "obase=2;$octet" | bc)
done |
echo $((2#$(cat)))
出力: 1113984275