Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am wanting to code a perl script that will convert a text file contents to binary numbers, these binary numbers are really ascii values. Anyone have any thoughts on what I am to expect. My reason is for learning perl more and playing around with different functions. Oh and I want to do it without using any modules this way I learn more better yes? :) oh yeah and of course I want to be able to convert the text file back to normal again.

Replies are listed 'Best First'.
Re: Suggestions
by tachyon (Chancellor) on Jul 06, 2001 at 19:28 UTC

    This converts all the data lines from a filehandle (I use DATA) to 7bit binary strings.

    while (my $line = <DATA>){ chomp $line; for (split//, $line) { print unpack "b7", $_; } print "\n"; } __DATA__ Hello World! -JAPH

    First we chomp off the newline. Then we get to the guts of it. How this works is the split//, $line part splits our line on null characters which generates an array/list which contains all the characters in line with each single character stored as an element of this array. The for iterates over this array and assigns each element to the magical $_ variable. We then use unpack to generate our bitstring. The "b7" specifies a 7 bit template which is sufficient for the ASCII char set. We then print each char (now a 7bit bitstring)in turn. We need to print a newline to maintain our file structure

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Suggestions
by VSarkiss (Monsignor) on Jul 06, 2001 at 19:30 UTC
    Do you mean you want to print out a file's contents, but substituting ascii code values instead of the characters? Umm, that's a one-liner: perl -e 'undef $/; print join(",", map {ord} split //, <>)'And the reverse is a one-liner also. Use chr instead of ord and switch where the comma and null character are: perl -e 'undef $/; print join("", map {chr} split /,/, <>)' Golf aside, deconstructing this will probably be instructive. Concepts that I've exploited here include:
    • The $/ variable determines what constitutes a "line" read by the <> operator. (See perlman:perlvar).
    • A null first argument to split breaks up the second argument into individual characters.1 (See perlman:perlfunc.)
    • The ord and chr functions essentially complement each other.
    • map is a powerful way to construct loops in Perl, in a style reminiscent of functional programming languages. (See perlman:perlfunc.)
    • To construct a string out of an array's elements, using a given string as separator, use join. In this sense, it's complementary to split. (See perlman:perlfunc also.)
    • The -e option to Perl allows you to execute a script directly from the command line. (See perlman:perlrun.)

    HTH

    1That gets tricky when dealing with multi-byte encodings, but ignore that for the moment....

      umm, I want to lets say take message.txt and convert its contents to ascii code values, only instead of converting for example e's to 101 I want the binary 1100101.
        for the 8 bit version (e.g. e becomes 01100101 (depending on arch)), the following should work (not tested, but should work) :
        while (<DATA>) { print unpack("b*",$_); } __END__ Just Another Perl Hacker

        may the foo be with you
Re: Suggestions
by tachyon (Chancellor) on Jul 06, 2001 at 19:28 UTC

    And this converts it back again

    while (my $line = <DATA>){ chomp $line; print pack "b7", $1 while $line =~ m/(.{7})/g; print "\n"; } __DATA__ 00010011010011001101100110111111011 111010111110110100111001101100100111000010 10110100101001100000100001010001001

    If you don't understand pack and unpack don't worry - neither do I really!

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Do I have to use 7bit binary?

        The answer is no but it does get a little more complex. Why don't you have a play with it and see?

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print