Net::OnlineCode::Decoder - Rateless Forward Error Correction Decoder


  use Net::OnlineCode::Decoder;
  use strict;

  # variables received from encoder:
  my ($msg_id, $e, $q, $msg_size, $blocksize);

  # calculated/local variables
  my (@check_blocks,@aux_blocks,$message,$block_id);
  my $mblocks = int(0.5 + ($msg_size / $blocksize));
  my $rng     = Net::OnlineCode::RNG->new($msg_id);

  my $decoder = Net::OnlineCode::Decoder->new(
    mblocks     => $mblocks,
    initial_rng => $rng,
    # ... pass e and q if they differ from defaults
  my $ablocks = $decoder->{ablocks};
  @aux_blocks = ( ( "\0" x $blocksize) x $ablocks);

  my ($done,@decoded) = (0);
  until ($done) {
    my ($block_id,$contents) = ...; # receive data from encoder
    push @check_blocks, $contents;


    # keep calling resolve until it solves no more nodes or we've
    # decoded all the message blocks
    while(1) {
      ($done,@decoded) = $decoder->resolve;
      last unless @decoded;

      # resolve returns a Bone object, which can be treated as an
      # array (see Net::OnlineCode::Bone for details):
      # $bone -> [0]     always 1
      # $bone -> [1]     ID of node that was solved
      # $bone -> [2.. ]  ID of nodes that need to be XORed

      # XOR check/aux blocks together to decode message/aux block
      foreach my $bone (@decoded) {
        my $block        = "\0" x $blocksize;
        my $nodes        = scalar(@$bone);
        my $decoded_node = $bone->[1];

        # XOR all component blocks
        foreach my $node (@{$bone}[2..$nodes - 1)) {
          if ($node < $mblocks) {                 # message block
              substr($message, $node * $blocksize, $blocksize))
          } elsif ($node < $mblocks + $ablocks) { # auxiliary block
              $aux_blocks[$node - $mblocks]);
          } else {                                # check block
              $check_blocks[$node - ($mblocks + $ablocks)]);

        # save newly-decoded message/aux block
        if ($decoded_block < $mblocks) {          # message block
          substr($message, $decoded_node * $blocksize, $blocksize) = $block;
        } else {                                  # auxiliary block
          $aux_blocks[$decoded_node - $mblocks] = $block;
      last if $done;
  $message = substr($message, 0, $msg_size);  # truncate to correct size
  print $message;                             # Done!


This module implements the "decoder" side of the Online Code algorithm for rateless forward error correction. Refer to the the Net::OnlineCode documentation for the technical background


See Net::OnlineCode for background information on Online Codes.

This module is part of the GnetRAID project. For project development page, see:


Declan Malone, <>


Copyright (C) 2013-2015 by Declan Malone

This package is free software; you can redistribute it and/or modify it under the terms of the "GNU General Public License" ("GPL").

The C code at the core of this Perl module can additionally be redistributed and/or modified under the terms of the "GNU Library General Public License" ("LGPL"). For the purpose of that license, the "library" is defined as the unmodified C code in the clib/ directory of this distribution. You are permitted to change the typedefs and function prototypes to match the word sizes on your machine, but any further modification (such as removing the static modifier for non-exported function or data structure names) are not permitted under the LGPL, so the library will revert to being covered by the full version of the GPL.

Please refer to the files "GNU_GPL.txt" and "GNU_LGPL.txt" in this distribution for details.


This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the "GNU General Public License" for more details.