File Coverage

blib/lib/Data/ID/URL/Shrink.pm
Criterion Covered Total %
statement 46 46 100.0
branch 11 12 91.6
condition 3 3 100.0
subroutine 10 10 100.0
pod 3 4 75.0
total 73 75 97.3


line stmt bran cond sub pod time code
1             package Data::ID::URL::Shrink;
2              
3 2     2   47550 use strict;
  2         6  
  2         83  
4 2     2   10 use warnings;
  2         9  
  2         65  
5              
6 2     2   13 use base 'Exporter';
  2         8  
  2         227  
7 2     2   1790 use POSIX qw(floor);
  2         13211  
  2         12  
8              
9             our @EXPORT_OK = qw(shrink_id stretch_id random_id);
10             our %EXPORT_TAGS = (
11             encoding => [qw(shrink_id stretch_id)],
12             all => [qw(shrink_id stretch_id random_id)]
13             );
14             our $VERSION = '0.02';
15              
16 2     2   2366 use constant SHRINKB50 => '023456789BCDFGHJKLMNPQRSTVWXYZbcdfghjkmnpqrstvwxyz';
  2         5  
  2         253  
17 2     2   13 use constant SHRINKSIZE => length SHRINKB50;
  2         4  
  2         1222  
18              
19             # Get an indexed character from the base dictionary.
20 620     620 0 1800 sub get_char_by_index { return substr(SHRINKB50, $_[0], 1); }
21              
22             sub shrink_id {
23 32     32 1 11857 my $dividend = shift;
24 32 100       154 return undef unless $dividend =~ /^\d+$/;
25 30 100       75 return get_char_by_index(0) if $dividend == 0;
26 28         35 my $id = '';
27 28         61 while($dividend >= SHRINKSIZE) {
28 46         48 my $remainder = $dividend % SHRINKSIZE;
29 46         70 $id = get_char_by_index($remainder) . $id;
30 46         160 $dividend = floor($dividend / SHRINKSIZE);
31             }
32 28         49 $id = get_char_by_index($dividend) . $id;
33 28         88 return $id;
34             }
35              
36             sub stretch_id {
37 16     16 1 41 my $id = shift;
38 16 50       35 return undef unless defined $id;
39 16         49 my @id_chars = split //, $id;
40 16 100       30 do { return undef unless (index(SHRINKB50, $_) >= 0) } for @id_chars;
  39         101  
41 15         29 my $val = 0;
42 15         28 while( scalar(@id_chars) ) {
43 38         55 my $char_val = index SHRINKB50, shift(@id_chars);
44 38         38 my $size = scalar(@id_chars);;
45 38         80 $val += $char_val * (SHRINKSIZE ** $size);
46             }
47 15         41 return $val;
48             }
49              
50             sub random_id {
51 36     36 1 15416 my $length = shift;
52 36 100       85 $length = defined $length ? $length : 11;
53 36 100 100     311 return undef unless $length =~ /^\d+$/ && $length > 2;
54 32         47 my $id = '';
55 32         201 $id .= get_char_by_index( int(rand(SHRINKSIZE)) ) for 1 .. $length;
56 32         164 return $id;
57             }
58              
59             1;
60              
61             =pod
62              
63             =head1 NAME
64              
65             Data::ID::URL::Shrink - Shorten numeric IDs, for nicer URLs and more.
66              
67             =head1 SYNOPSIS
68              
69             use Data::ID::URL::Shrink qw(:all);
70             -- or --
71             use Data::ID::URL::Shrink qw(:encoding);
72              
73             my $id = shrink_id(123456789); # shorten your numeric ID.
74             my $numeric_id = stretch_id($id); # get your numeric ID back.
75              
76             =head1 DESCRIPTION
77              
78             L will shorten a numeric ID, and can randomly generate
79             IDs for you, based on its own Base50 character set.
80            
81             By default, a random_id() call will return an 11-character id. Optionally, you can
82             generate IDs of specific character lengths, but no shorter than 3 characters.
83              
84             This module DOES NOT GUARANTEE unique IDs. It supplements them.
85              
86             =head1 FUNCTIONS
87              
88             Export functions individually or use tags -- ':encoding' or ':all'.
89              
90             =head2 shrink_id
91              
92             my $id = shrink_id(123456789);
93              
94             Give this function a numeric ID and get a shorter, encoded one in return.
95              
96             =head2 stretch_id
97              
98             my $numeric_id = stretch_id($id);
99              
100             Get a numeric value back from a previously encoded id.
101              
102             =head2 random_id
103              
104             # NOTE: If argument is passed, must be n > 2.
105             my $id = random_id(); # Generate a random 11-character ID.
106             my $id = random_id(n); # Generate a random n-character ID.
107              
108             Just remember: the lower the character length value, the smaller the set of
109             possible unique IDs.
110              
111             =head1 ACKNOWLEDGEMENTS
112              
113             =head2 mst
114              
115             Thanks for help with the module name and answering PAUSE and CPAN questions.
116              
117             =head2 internets
118              
119             Thanks to the authors of the articles, Q&A posts, etc. which I read to get
120             this module working.
121              
122             =head1 AVAILABILITY
123              
124             GitHub L
125              
126             =head1 COPYRIGHT
127              
128             Copyright (C) 2013 Rick Yakubowski (yakubori)
129              
130             =head1 LICENSE
131              
132             This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
133              
134             =head1 AUTHOR
135              
136             Rick Yakubowski (yakubori)
137              
138             =cut