Number-RecordLocator

 view release on metacpan or  search on metacpan

lib/Number/RecordLocator.pm  view on Meta::CPAN


our $VERSION = '0.005';

use warnings;
use strict;
use Carp;
use bigint;

use vars qw/%CHAR_TO_INT %INT_TO_CHAR $INITIALIZED %CHAR_REMAP/;

=head1 NAME

Number::RecordLocator - Encodes integers into a short and easy to read and pronounce "locator string"


=head1 SYNOPSIS

    use Number::RecordLocator;

    my $generator = Number::RecordLocator->new();
    my $string = $generator->encode("123456");

    # $string = "5RL2";

    my $number = $generator->decode($string);
  
    # $number = "123456";

    
=head1 DESCRIPTION

C<Number::RecordLocator> encodes integers into a 32 character "alphabet" 
designed to be short and easy to read and pronounce.  The encoding maps:
    
    0 to O
    1 to I
    S to F 
    B to P

With a 32 bit encoding, you can map 33.5 million unique ids into a 5 character
code.
 
This certainly isn't an exact science and I'm not yet 100% sure of the encoding.
Feedback is much appreciated.


=cut


=head2 new 

Instantiate a new C<Number::RecordLocator> object. Right now, we don't
actually store any object-specific data, but in the future, we might.


=cut

sub new {
    my $class = shift;
    my $self = {};
    bless $self => $class;
    $self->init unless ($INITIALIZED); 
    return $self;
}


=head2 init

Initializes our integer to character and character to integer mapping tables.

=cut

sub init {

  my $counter = 0;
  for ( 2 .. 9, 'A', 'C' .. 'R', 'T' .. 'Z' ) {
    $CHAR_TO_INT{$_}       = $counter;
    $INT_TO_CHAR{$counter} = $_;
    $counter++;
  }

  $CHAR_REMAP{'0'} = 'O';
  $CHAR_REMAP{'1'} = 'I';
  $CHAR_REMAP{'S'} = 'F';
  $CHAR_REMAP{'B'} = 'P';

  while (my ($from, $to) = each %CHAR_REMAP) {
      $CHAR_TO_INT{$from} = $CHAR_TO_INT{$to};
  }
  $INITIALIZED      = 1;
}

=head2 encode INTEGER

Takes an integer. Returns a Record Locator string.

=cut

sub encode {
  my $self    = shift;
  my $integer = shift;
  return undef unless ($integer =~ /^\d+$/);
  my @numbers;
  while ( $integer != 0 ) {
    unshift @numbers, $integer % 32;
    $integer = int( $integer / 32 );
  }

  my $str = join( '', map { $INT_TO_CHAR{$_} } @numbers );
  return $str;
}

=head2 decode STRING

Takes a record locator string and returns an integer. If you pass in 
a string containing an invalid character, it returns undef.

=cut

sub decode {
    my $self = shift;

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.575 second using v1.00-cache-2.02-grep-82fe00e-cpan-1925d2aa809 )