Algorithm-Hamming-Perl
view release on metacpan or search on metacpan
#!/bin/perl
#
# Perl.pm - Algorithm::Hamming::Perl library. Implements 8,4 bit Hamming ECC.
#
# This code will be unusual to read - instead of finding the Hamming
# algorithm you will see hash after hash after hash. These are used to
# improve the speed of the library, and act as a cache of preprocessed
# results. An optional subrourine may be run:
# Algorithm::Hamming::Perl::hamming_faster()
# which uses a bigger cache for faster encoding/decoding (but more memory
# and slower startups).
#
# 18-Oct-2003 Brendan Gregg Created this.
package Algorithm::Hamming::Perl;
use 5.006;
use strict;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(hamming unhamming unhamming_err);
our $VERSION = '0.05';
my %Hamming8raw; # This hash is used during initialisation only. It
# contains binary text keys and binary text values
# as [data] -> [Hamming code] lookups,
# eg "00001010" => "000001010010"
my %Hamming8semi; # This hash is semi-processed, and is used in "slow"
# encoding mode. It contains byte keys and binary
# text values as [data] -> [Hamming code] lookups,
# eg "A" => "010010000100"
my %Hamming8by2; # This hash is fully-processed and provides speed at
# the cost of memory. It contains 2 byte keys and
# 3 byte values as [data] -> [Hamming code] lookups,
# eg "AA" => "HD " # (whatever the code is!)
# By using this hash, the program can read an
# input stream 2 bytes at a time, writing an output
# stream 3 bytes at a time - no messing aroung
# with half bytes or byte boundaries.
my %Hamming8rev; # This hash is semi-processed, and is used for
# decoding Hamming code to data. It contains
# binary text values for keys and bytes for values
# as [Hamming code] -> [data] lookups,
# eg "010010000100" => "A"
my %Hamming8by2rev; # This hash is fully-processed and provides speed at
# the cost of memory. It contains 3 byte keys and
# 2 byte values as [Hamming code] -> [data] lookups,
# eg "HD " => "AA" # (whatever the code is!)
# By using this hash, the program can read an
# input stream 3 bytes at a time, writing an output
# stream 2 bytes at a time - no messing aroung
# with half bytes or byte boundaries.
my ($x,$y,$key,$char,$char1,$char2,$chars,$char_out,$ham_text,$number);
#
# Hamming8raw is NOT the lookup table used! :)
# (that would be dreadfully inefficient).
# This hash is processed into a bytes -> bytes lookup.
#
%Hamming8raw = ("00000000" => "000000000000",
"00000001" => "000000000111",
"00000010" => "000000011001",
"00000011" => "000000011110",
"00000100" => "000000101010",
"00000101" => "000000101101",
"00000110" => "000000110011",
"00000111" => "000000110100",
"00001000" => "000001001011",
"00001001" => "000001001100",
"00001010" => "000001010010",
"00001011" => "000001010101",
"00001100" => "000001100001",
"00001101" => "000001100110",
"00001110" => "000001111000",
"00001111" => "000001111111",
"00010000" => "000110000001",
"00010001" => "000110000110",
"00010010" => "000110011000",
"00010011" => "000110011111",
"00010100" => "000110101011",
"00010101" => "000110101100",
"00010110" => "000110110010",
"00010111" => "000110110101",
"00011000" => "000111001010",
"00011001" => "000111001101",
"00011010" => "000111010011",
"00011011" => "000111010100",
"00011100" => "000111100000",
"00011101" => "000111100111",
"00011110" => "000111111001",
"00011111" => "000111111110",
"00100000" => "001010000010",
"00100001" => "001010000101",
"00100010" => "001010011011",
"00100011" => "001010011100",
"00100100" => "001010101000",
"00100101" => "001010101111",
"00100110" => "001010110001",
"00100111" => "001010110110",
"00101000" => "001011001001",
"00101001" => "001011001110",
"00101010" => "001011010000",
"00101011" => "001011010111",
"00101100" => "001011100011",
"00101101" => "001011100100",
"00101110" => "001011111010",
"00101111" => "001011111101",
"00110000" => "001100000011",
"00110001" => "001100000100",
"00110010" => "001100011010",
"00110011" => "001100011101",
"00110100" => "001100101001",
"00110101" => "001100101110",
"00110110" => "001100110000",
"00110111" => "001100110111",
"00111000" => "001101001000",
"00111001" => "001101001111",
"00111010" => "001101010001",
1;
__END__
# Below is stub documentation for your module. You better edit it!
=head1 NAME
Algorithm::Hamming::Perl - Perl implementation of ECC Hamming encoding,
for single bit auto error correction.
=head1 SYNOPSIS
use Algorithm::Hamming::Perl qw(hamming unhamming);
$code = hamming($data); # Encode $data
$data = unhamming($code); # Decode and fix errors
($data,$errors) = unhamming($code); # + return error count
=head1 DESCRIPTION
This is an Error Correction Code module, implementing Hamming encoding
(8 bits data, 4 bits Hamming - ie increases data size by 50%). Data can
be encoded so that single bit errors within a byte are auto-corrected.
This may be useful as a precaution before storing or sending data where
single bit errors are expected.
Hamming encoding was invented by Richard Hamming, Bell Labs, during 1948.
=head1 EXPORT SUBROUTINES
=over 4
=item hamming (SCALAR)
Returns the Hamming code from the provided input data.
=item unhamming (SCALAR)
Returns the original data from the provided Hamming code. Single bit errors
are auto corrected.
=item unhamming_err (SCALAR)
Returns the original data from the provided Hamming code, and a number counting
the number of bytes that were corrected. Single bit errors are auto corrected.
=back
=head1 OTHER SUBROUTINES
=over 4
=item Algorithm::Hamming::Perl::hamming_faster ()
This is an optional subroutine that will speed Hamming encoding if it is
run once at the start of the program. It does this by using a larger (hash)
cache of preprocessed results. The disadvantage is that it uses more memory,
and can add several seconds to invocation time. Only use this if you are
encoding more than 1 Mb of data.
=back
=head1 INSTALLATION
perl Makefile.PL
make
make test
make install
=head1 DEPENDENCIES
ExtUtils::MakeMaker
=head1 EXAMPLES
See the example perl programs provided with this module "example*".
An encoding and decoding example,
use Algorithm::Hamming::Perl qw(hamming unhamming);
$data = "Hello";
$hamcode = hamming($data);
$original = unhamming($hamcode);
=head1 LIMITATIONS
This is Perl only and can be slow. The Hamming encoding used can only
repair a single bit error within a byte - ie if two bits are damaged within
the one byte then this encoding cannot auto correct the error.
=head1 BUGS
Try not to join Hamming encoded strings together - this may give results
that look like a bug. If an odd number of input byes is encoded, the output
code is short half a byte - and so is padded with '0' bits. Joining these
with a string concatenation will contain the padding bits that will confuse
decoding.
The above problem can occur when inputing and outputing certain lengths
to filehandles. To be safe, my example code uses a buffer of 3072 bytes -
a safe size to use with filehandles.
=head1 COPYRIGHT
Copyright (c) 2003 Brendan Gregg. All rights reserved.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself
=head1 AUTHOR
Brendan Gregg <brendan.gregg@tpg.com.au>
[Sydney, Australia]
=cut
( run in 1.783 second using v1.01-cache-2.11-cpan-39a47a84364 )