-
Notifications
You must be signed in to change notification settings - Fork 2
/
Minimal.pm
148 lines (98 loc) · 3.19 KB
/
Minimal.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use strict;
use warnings;
package Net::IPAddress::Minimal;
# ABSTRACT: IP string to number and back
use Data::Validate 'is_integer';
use Data::Validate::IP 'is_ipv4';
use base 'Exporter';
our @EXPORT_OK = qw( ip_to_num num_to_ip invert_ip );
sub test_string_structure {
my $string = shift || q{};
is_ipv4($string) && return 'ip';
is_integer($string) && return 'num';
$string || return 'empty';
return 'err';
}
sub ip_to_num {
# Converting between IP to number is according to this formula:
# IP = A.B.C.D
# IP Number = A x (256**3) + B x (256**2) + C x 256 + D
my $ip = shift;
my ( $Aclass, $Bclass, $Cclass, $Dclass ) = split /\./, $ip;
my $num = (
$Aclass * 256**3 +
$Bclass * 256**2 +
$Cclass * 256 +
$Dclass
);
return $num;
}
sub num_to_ip {
my $ipnum = shift;
my $z = $ipnum % 256;
$ipnum >>= 8;
my $y = $ipnum % 256;
$ipnum >>= 8;
my $x = $ipnum % 256;
$ipnum >>= 8;
my $w = $ipnum % 256;
my $ipstr = "$w.$x.$y.$z";
return $ipstr;
}
sub invert_ip {
my $input_str = shift;
my $result = test_string_structure($input_str);
my %responses = (
ip => sub { ip_to_num($input_str) },
num => sub { num_to_ip($input_str) },
err => sub { 'Illegal string. Please use IPv4 strings or numbers.' },
empty => sub { 'Empty string. Please use IPv4 strings or numbers.' },
);
# This is a dispatch table, instead of a big ugly if block / switch
if ( exists $responses{$result} ) {
return $responses{$result}->();
}
# If none of the above was executed
die 'Could not convert IP string / number due to unknown error';
}
1;
__END__
=head1 SYNOPSIS
This module converts IPv4 strings to integer IP numbers and vice versa.
It's built to be used as quickly and easily as possible, which is why you can
just simply use the C<invert_ip> function.
It recognizes whether you have an IPv4 string or a number and converts it to the
other form.
Here's a sample script:
use Net::IPAddress::Minimal ('invert_ip');
my $input_string = shift @ARGV;
my $output = invert_ip( $input_string );
print "$output\n";
=head1 EXPORT
Three functions can be exported:
=over 4
=item * invert_ip
=item * num_to_ip
=item * ip_to_num
=back
=head1 SUBROUTINES/METHODS
=head2 invert_ip
Gets an IPv4 string or an IP number and converts it to the other form.
my $ip_num = invert_ip( '10.200.10.130' );
# $ip_str = 180882050
my $ip_num = invert_ip( 180882050 );
# $ip_str = '10.200.10.130';
=head2 num_to_ip
Gets an IP number and returns an IPv4 string.
my $ip_num = num_to_ip( 3232235778 );
# $ip_str = '192.168.1.2';
=head2 ip_to_num
Gets a IPv4 string and returns the matching IP number.
my $ip_num = ip_to_num( '212.212.212.212' );
# $ip_num = 3570717908
=head2 test_string_structure
Checks the structure of the input string and returns flags indicating whether
it's an IPv4 string, and IP number or something else (which is an error).
=head1 BUGS
We encourage you to open bugs on the Github Issues page:
L<http://github.com/Tlousky/net-ipaddress-minimal/issues>.