Number::Encode - Encode bit strings into digit strings


Number-Encode documentation Contained in the Number-Encode distribution.

Index


Code Index:

NAME

Top

Number::Encode - Encode bit strings into digit strings

SYNOPSIS

Top

  use Number::Encode qw(nonuniform uniform);

DESCRIPTION

Top

Provides a mechanism to convert arbitrary bit-strings into numeric digit strings. The transformation can be uniform or non-uniform depending on the type of distribution of the numeric digits achieved.

The former approach is useful for security-related applications such as calling cards and the such, which require a uniform digit distribution. The algorythm used to generate uniform distributions, while deterministic, is more constly than the non-uniform variant.

This module is distributed under the same terms and warranty as Perl itself.

EXPORT

This module provides the following exports:

my $number = nonuniform($data)

Converts a bit-string represented in the example by the scalar $data to a numeric string representation returned at $number.

The probabilistic distribution of the digits in the resulting number is not uniform. Some digits will have up to twice the chance of others of appearing at a given position.

my $number = uniform($data)

Performs a transformation from the bit-string provided in $data to a numeric string returned at $number. This transformation is a bit more costly but has the advantage that the digit distribution is uniform. This function is adequate for applications that require a uniform composition of the numeric strings, such as password or PIN number generators.

HISTORY

Top

1.00

Original version; created by h2xs 1.20 with options

  -ACOXfn
	Number::Encode
	-v
	1.00

AUTHOR

Top

Luis E. Munoz <lem@cantv.net>

SEE ALSO

Top

perl(1).


Number-Encode documentation Contained in the Number-Encode distribution.

package Number::Encode;

require 5.005_62;
use strict;
use warnings;
use Digest::MD5 qw(md5);

require Exporter;

our @ISA = qw(Exporter);

our %EXPORT_TAGS = ( 'all' => [ qw(nonuniform uniform) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our $VERSION = '1.00';

sub uniform ($) {
    my $data = shift;
    my $char = 0;
    my $carry = 0;
    my $cbits = 0;
    my $hsh = '';

    for my $c (split(//, $data))
    {
	
	$carry <<= 8;
	$carry += ord($c);
	$cbits += 8;

	while ($cbits >= 4) {

	    my $n;

	    if ($cbits >= 4) {	# More than 4 bits available
		$n = $carry & 0xF;
		if ($n > 9) {
		    $n ^= vec(md5($hsh . $carry . $n), $n, 4);
		    $n &= 0x7 if $n > 9;
		}
		$carry >>= 4;
		$cbits -= 4;
	    }

	    $hsh .= chr(ord('0') + $n);
	}
    }

    if ($cbits) {
	$hsh .= chr(ord('0') + $carry);
    }

    return $hsh;
}

sub nonuniform ($) {
    my $data = shift;
    my $char = 0;
    my $carry = 0;
    my $cbits = 0;
    my $hsh = '';

    for my $c (split(//, $data))
    {
	$carry <<= 256;
	$carry += ord($c);
	$cbits += 8;

	while ($cbits >= 4) {

	    my $n;

	    if ($cbits >= 4) {	# More than 4 bits available
		$n = $carry & 0xF;
		if ($n <= 9) {
		    $carry >>= 4;
		    $cbits -= 4;
		}
	    }

	    if ($cbits == 3 or $n > 9) {
		$n = $carry & 0x7;
		$carry >>= 3;
		$cbits -= 3;
	    }
	    $hsh .= chr(ord('0') + $n);
	}
    }

    if ($cbits) {
	$hsh .= chr(ord('0') + $carry);
    }

    return $hsh;
}

1;
__END__