#!/usr/bin/perl

# $message_out = one_time_pad( $message_in, $pad, $pos )
#
# Encrypt or decrypt $message_in using the bits starting at
# $pos in the file $pad.  Discard the bits when they
# have been used.  (Don't try to decrypt messages out of order.
# You will have discarded the pad bits needed for the second
# message when you processed the out-of-order first message.
# Your system must support the truncate function.)
#
sub one_time_pad {
    my ( $msg, $pad, $pos ) = @_;
    my $len = length( $msg );

    return undef
        if $pos < 0
        or ! -f $pad
        or ($pos + $len) > -s _;

    open PAD, "<$pad" or return undef;
    seek PAD, 2, -$pos or return undef;
    my $key;
    sysread PAD, $key, $len or return undef;
    close PAD;
    truncate $pad, $pos;

    return ($msg ^ $key);
}
