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

How can I open a file in hexadecimal form? I need to open a hexadecimal file and assign the entire contents to a variable. Then I need to search the variable for a specific hexadecimal character (ex: A7) and then replace that character with the hexadecimal character 00. Then I need to print the variable to a file in hexadecimal form. How can I do this? Thanks.

Edited by Arunbear: Changed title from 'hexadecimal', as per Monastery guidelines

  • Comment on How to open a file in hexadecimal form?

Replies are listed 'Best First'.
Re: How to open a file in hexadecimal form?
by Roy Johnson (Monsignor) on May 12, 2005 at 02:12 UTC
    Do you mean an ASCII file of hexadecimal numbers, or do you just mean a binary file? Do you know how to open a file, and do you know about binmode? Then you might want to read about read and substr or s.

    Caution: Contents may have been coded under pressure.
Re: How to open a file in hexadecimal form?
by graff (Chancellor) on May 12, 2005 at 02:59 UTC
    If the file actually contains text that consists entirely of hexadecimal digit characters -- e.g. a file is ten bytes long (plus LF or CRLF line-termination, perhaps), and contains just characters like this:
    B58013A7FF
    then one plan would be to group the string of hex digits into pairs then replace the ones that are "A7" with "00" and rebuild the string -- something like this would do it:
    while (<DATA>) { chomp; my $out = ''; while ( /([0-9a-f]{2})/gi ) { $out .= ( uc($1) eq 'A7' ) ? "00" : $1; } print "$out\n"; } __DATA__ b58013A7FF
    On the other hand, if you want to treat the file as binary data, and any single byte in the file that happens to have the value 0xA7 (i.e. 167. decimal, 10100111 binary) should be replaced by a null byte, then the plan would be read some number of raw bytes into a scalar, replace 0xA7 with 0x00 throughout, and write the result -- something like this (set up as a stdin > stdout filter):
    binmode STDIN; binmode STDOUT; $/ = \8192; # set "input record separator" to 8KB per read while (<>) { tr/\xa7/\x00/; print; }
    In case you don't know about stdin > stdout filters, it's just a matter of running the script using redirection from some file for input and redirection to some other file for output, like this:
    script.pl < input.file > output.file
      It's a binary file that I need to edit. The following code works perfectly:

      binmode STDIN;
      binmode STDOUT;
      $/ = \8192; # set "input record separator" to 8KB per read

      while (<>) {
      tr/\xa7/\x00/;
      print;
      }


      Is it possible to look for more than one hexadecimal number back to back. For example, if I wanted to search the variable for all instances of x31 x33 x39 x37 (not appearing individually but appearing as 1397) how could I replace a set of four hexadecimal numbers with x00 x00 x00 x00 ? And I'm sure this is probably a stupid question, but why does the input record separator need to be set at 8kb? Thanks.
        <code></code> tags are the preferred way to post formatted plain text here.

        The input record separator needs to be set to something, and 8kb is a reasonable value. It shouldn't be "\n" because you might not have any. But you can use it for your new problem:

        $/ = '1397'; # You don't have to specify the hex numbers; it's all th +e same to Perl while (<>) { # 1397 appears at the end of the record, if at all # so an anchored search-and-replace handles it s/1397$/\0\0\0\0/; }

        Caution: Contents may have been coded under pressure.
Re: How to open a file in hexadecimal form?
by mrborisguy (Hermit) on May 12, 2005 at 02:11 UTC