Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
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 musing on the Monastery: (5)
As of 2025-03-26 07:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When you first encountered Perl, which feature amazed you the most?










    Results (67 votes). Check out past polls.

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.