# subroutine to check if host cpu uses little or big-endian byte ordering # returns 0 if little, 1 if big sub endiancheck { my ($x, $y); $x = pack("i",65); # pack 'A' as a signed 32bit int # now $x can be considered a 4-byte string $y = substr($x,3,1); #extract last byte if (ord($y)==65) {return 1;} # big endian return 0; # little endian } # Here's how you might write the same procedure in C: # int endiancheck() # { unsigned int x = 65; # return *((char*)&x+3); // return value of 3rd byte offset from &x # } // which would be 0 (false) if it's little endian # # C is clearly more adept at binary data processing than Perl. On the # other hand, thinking about strings as char* can be a bit nasty! # Subroutines to convert from host to network byte ordering. # They must be called prior to unpack. sub htons { my $x = shift; if ($byteorder==1) { return $x; } # no need to do anything # switch bytes my ($a,$b); $a = substr($x,0,1); $b = substr($x,1,1); $x = pack("CC",ord($b),ord($a)); return $x; } sub htonl { my $x = shift; if ($byteorder==1) { return $x; } # switch my @a; $a[0] = substr($x,0,1); $a[1] = substr($x,1,1); $a[2] = substr($x,2,1); $a[3] = substr($x,3,1); $x = pack("CCCC",ord($a[3]),ord($a[2]),ord($a[1]),ord($a[0])); return $x; } sub htond { my $x = shift; if ($byteorder==1) { return $x; } # switch my @a; $a[0] = substr($x,0,1); $a[1] = substr($x,1,1); $a[2] = substr($x,2,1); $a[3] = substr($x,3,1); $a[4] = substr($x,4,1); $a[5] = substr($x,5,1); $a[6] = substr($x,6,1); $a[7] = substr($x,7,1); $x = pack("CCCCCCCC",ord($a[7]),ord($a[6]),ord($a[5]),ord($a[4]),ord($a[3]),ord($a[2]),ord($a[1]),ord($a[0])); return $x; } sub ntohs { htons($_[0]); } sub ntohl { htonl($_[0]); } sub ntohd { htond($_[0]); } $byteorder = endiancheck(); 1;