Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Detecting machine Endian-ness

by LunaticLeo (Scribe)
on Aug 06, 2001 at 20:53 UTC ( [id://102506]=CUFP: print w/replies, xml ) Need Help??

I am playing around with raw sockets and manufactured packets in pure-perl (no Net::Pcap etc). Along the way I figured I needed to know the whether the machine was big-endian (network order) or little-endian.

Actually, I don't need to know this, but here is the code for detecting endianness for normal big and little 32bit machines. Extensions for 64bit welcome; but this works for me on Linux-IA32 and Solaris2.6-UltraSparc .

@b = unpack('CCCC', pack('I', 0x04030201)); if ($b[0] == 4 and $b[1] == 3 and $b[2] == 2 and $b[3] == 1 ) { print "big-endian\n"; } elsif ($b[0] == 1 and $b[1] == 2 and $b[2] == 3 and $b[3] == 4 ) { print "little-endian\n"; } else { print "funky-endian\n"; }

Replies are listed 'Best First'.
(tye)Re: Detecting machine Endian-ness
by tye (Sage) on Aug 06, 2001 at 23:24 UTC

    That is close to a test I've used:

    my $o= pack( 'I', 0x04030201 ); if( substr($o,-4) eq "\04\03\02\01" ) { return "big"; } elsif( substr($o,0,4) eq "\01\02\03\04" ) { return "little"; } else { die "Strange endian"; }
    Note that the "I" format can result in more than 4 bytes on some platforms.

            - tye (but my friends call me "Tye")
      Is substr() offset always in bytes?

      Note that the "I" format can result in more than 4 bytes on some platforms.

      Yeah, I suppose you could use 'L' then.

      I suppose you could figure out the size of integers with code like:

      @b = unpack('C*', pack('I', 0)); return scalar(@b);

      Then you could make the endian code more generic with:

      @b = unpack('C*', pack('I', 0)); $sizeof_long = scalar(@b); @c = (1..$sizeof_long); $i = pack('I', hex('0x0'.join('0',reverse @c))); $big = pack('C'.$sizeof_long, reverse @c); $lit = pack('C'.$sizeof_long, @); if ( substr($i, 0, $sizeof_long) eq $big ) { return 'big'; } elsif ( substr($i, 0, $sizeof_long) eq $lit ) { return 'little'; } else { return "strange"; }

        Good point. I don't do anything with "wide" strings in Perl yet so I usually forget to take that into consideration. But here we are making the strings so we know they'll be byte strings and we can use what I wrote or: length pack "I", 0 to find the number of bytes in an IV.

        I thought I had used a "native 32-bit integer" before for endianness testing, but for some reason couldn't think of "L". That certainly makes more sense than resorting to substr. (:

                - tye (but my friends call me "Tye")
Re: Detecting machine Endian-ness
by jmcnamara (Monsignor) on Aug 07, 2001 at 15:26 UTC

    For dealing with the endianess of integers the $Config{byteorder} variable available from the core Config module should be sufficient:
    #!/usr/bin/perl -w use strict; use Config; if ($Config{byteorder} == 4321) { print "Big endian\n"; } elsif ($Config{byteorder} == 1234) { print "Little endian\n"; } elsif ($Config{byteorder} == 87654321) { print "Cray\n"; } elsif ($Config{byteorder} == 3412) { print "Weird order\n"; } else { # Not sure if it can get here print "Unknown byte order\n"; }


    John.
    --

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://102506]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-04-25 23:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found