0

perlで文字列をbase36(0-9,az)に変換するにはどうすればよいですか?

IP アドレスを 1 対 1 のマップで base36 に変換したいので、それらを URL で使用できます。

127.0.0.1 === 文字列 ==> 127000000001=== base36 ==>

72.98.234.11 === 文字列 ==> 072098234011=== base36 ==>

4

2 に答える 2

4

基数 10 で十分ではありませんか? [0-4294967295] (1 桁から 10 桁) の数値が得られます。これは、私たちが取得しようとしていたものよりもわずかに長いだけです (1 ~ 8 桁)。

$ perl -E'say unpack "N", pack "C4", split /\./, $ARGV[0]' 127.0.0.1
2130706433

$ perl -E'say unpack "N", pack "C4", split /\./, $ARGV[0]' 72.98.234.11
1214441995

完全にリバーシブル:

$ perl -E'say join ".", unpack "C4", pack "N", $ARGV[0]' 2130706433
127.0.0.1

$ perl -E'say join ".", unpack "C4", pack "N", $ARGV[0]' 1214441995
72.98.234.11

CPAN の任意の数のモジュールを使用して、その数値を 10 以外の別の基数に変換できます。

base 10: 1-10 digits
base 16: 1-8 digits    # Can be done very efficiently
base 32: 1-7 digits    # Can be done very efficiently
base 36: 1-7 digits
base 62: 1-6 digits
base 64: 1-6 digits    # Can be done very efficiently

ベース 16:

sub pack_ip { sprintf "%X", unpack "N", pack "C4", split /\./, $_[0] }

sub unpack_ip { join ".", unpack "C4", pack "N", hex $_[0] }

Base 64: (これはかなり高速なはずです。C に移植しても高速です。)

my @syms = ('0'..'9', 'A'..'Z', 'a'..'z', '_', '-');
my %syms = map { $sym[$_] => $_ } 0..$#syms;

sub pack_ip {
   my $num = unpack "N", pack "C4", split /\./, $_[0];
   my $base64 = join '', @syms[
      ($num >> 30) & 0x3F,
      ($num >> 24) & 0x3F,
      ($num >> 18) & 0x3F,
      ($num >> 12) & 0x3F,
      ($num >>  6) & 0x3F,
      ($num >>  0) & 0x3F,
   ];
   $base64 =~ s/^A+(?!\z)//;
   return $base64;
}

sub unpack_ip {
   my $num;
   $num = ($num << 6) | $sym{$_}
      for split //, $_[0];
   return join ".", unpack "C4", pack "N", $num;
}
于 2012-09-26T21:41:33.420 に答える
-1

Why don't you use base 16 since that's basically what an IP address is anyway?

sub ip_to_hex {
  join('', map { sprintf('%02x', $_) } split(/\./, shift));
}

sub hex_to_ip {
  join('.', map { hex($_) } shift =~ m/([0-9a-f]{2})/g);
}

say ip_to_hex('127.0.0.1');    # 7f000001
say ip_to_hex('72.98.234.11'); # 4862ea0b
say hex_to_ip('4862ea0b');     # 72.98.234.11
于 2012-09-26T22:24:39.687 に答える