james28909
james28909

Reputation: 574

byte swap with perl

I am reading a file, containing integers using the "33441122" byte order. How can I convert the file to the "11223344" (big endian) byte order? I have tried a few things, but I am really lost.

I have read a lot about Perl, but when it comes to swapping bytes, I'm in the dark. How can I convert this:

33 44 11 22

into this:

11 22 33 44

using Perl.

Any input would be greatly appreciated :)

Upvotes: 1

Views: 2941

Answers (2)

Borodin
Borodin

Reputation: 126722

I think the best way is to read two bytes at a time and dwap them before outputting them.

This program creates a data file test.bin, and then reads it in, swapping the bytes as described.

use strict;
use warnings;

use autodie;

open my $fh, '>:raw', 'test.bin';
print $fh "\x34\x12\x78\x56";

open my $out, '>:raw', 'new.bin';
open $fh, '<:raw', 'test.bin';

while (my $n = read $fh, my $buff, 2) {
  $buff = reverse $buff if $n == 2;
  print $out $buff;
}

Upvotes: 1

Olaf Dietsche
Olaf Dietsche

Reputation: 74028

You can read 4 bytes at a time, split it into individual bytes, swap them and write them out again

#! /usr/bin/perl

use strict;
use warnings;

open(my $fin, '<', $ARGV[0]) or die "Cannot open $ARGV[0]: $!";
binmode($fin);
open(my $fout, '>', $ARGV[1]) or die "Cannot create $ARGV[1]: $!";
binmode($fout);

my $hexin;
my $n;
while (($n = read($fin, $bytes_in, 4)) == 4) {
    my @c = split('', $bytes_in);
    my $bytes_out = join('', $c[2], $c[3], $c[0], $c[1]);
    print $fout $bytes_out;
}

if ($n > 0) {
    print $fout $bytes_in;
}

close($fout);
close($fin);

This will be called on the command line as

perl script.pl infile.bin outfile.bin

outfile.bin will be overwritten.

Upvotes: 3

Related Questions