I've put together a couple of subroutines to pack and unpack binary strings. They allow for any length of string by prepending the original string length to the packed string so that the right string length can be used in the unpack template, e.g. b45 rather than b*. That way you don't get extra zeros padding the unpacked binary string. Here is a script that tests packing and unpacking random binary strings of a given length one hundred times. I have tested with strings of 12000 digits with no problem.

Here it is

use strict; use warnings; # Get and length of binary string to test from # command line and validate. # my $teslLen = shift or die qq{No string length supplied\n}; die qq{Length supplied not integer\n} unless $teslLen =~ /^\d+$/; # Test one hundred strings of requested length. # for (1 .. 100) { print qq{\nIteration $_\n}; # Create string and print it's length. # my $binStr = makeBinStr($teslLen); print qq{Original length is @{[length $binStr]}\n}; # Pack string, show packed length. # my $packedStr = packBinStr($binStr); print qq{ Packed length is @{[length $packedStr]}\n}; # Reconstruct original, show length again. # my $unpackedStr = unpackBinStr($packedStr); print qq{Unpacked length is @{[length $binStr]}\n}; # Die unless original and reconstructed match. # die q{Unpacked does not match original}, qq{\n$binStr\n$unpackedStr\n} unless $binStr eq $unpackedStr; } # Make a random binary string of requested length. # sub makeBinStr { my $digits = shift; my $str = q{}; $str .= int rand 2 for 1 .. $digits; return $str; } sub packBinStr { # Get binary string and validate. # my $unpacked = shift; die qq{String not binary\n} unless $unpacked =~ /^[01]+$/; # Get length of binary string, pack the string using # correct length in the template. Prepend length and an # asterisk to packed string so that correct length # can be used when unpacking later. Return packed string. # my $len = length $unpacked; my $packed = qq{$len*} . pack qq{b$len}, $unpacked; return $packed; } sub unpackBinStr { # Get packed string and split on asterisk, use three- # argument split so that we only get two fields back # in case the packed string contains an asterisk. # my $packed = shift; my ($len, $packStr) = split /\*/, $packed, 2; # Unpack using correct length in template, return # binary string. # my $unpacked = unpack qq{b$len}, $packStr; return $unpacked; }

Give it an argument of the length of string you want to test.

I hope that it is useful.

Cheers,

JohnGG


In reply to Re: Binary string to base64 by johngg
in thread Binary string to base64 by albert

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.