Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: Help me decipher code containing map function

by BrowserUk (Patriarch)
on May 20, 2017 at 03:35 UTC ( [id://1190694]=note: print w/replies, xml ) Need Help??


in reply to Help me decipher code containing map function

I thought that the map function takes in a list(perhaps an array), I do not see the above code having a list passed to it.

unpack outputs a list. In this case it extracts a list of 6 numbers (ascii values) from the (first) 6 bytes in $octetstr.

It then uses map to iterate over those 6 numbers converting them to 2-digit hex strings and appending them to $val

Before spliting them (the 2-digit hex strings) back apart and then joining them again interspersed with ':'s.

It is an altogether overcomplicated and clumsy piece of code. The whole process can be done with just $mac = join ':', unpack '(H2)*', $octetstr;

Ie. Given:

$octetstr = join '', map chr(), 0xab, 0xcd, 0x00, 0x1d, 0x94, 0x56;;

Instead of:

val = ''; map { $val .= sprintf("%02x",$_) } unpack "CCCCCC", $octetstr;; $mac = join( ":", unpack("a2 a2 a2 a2 a2 a2", $val ) );; print $mac;; ab:cd:00:1d:94:56

You could just do:

$mac = join ':', unpack '(H2)*', $octetstr;; print $mac;; ab:cd:00:1d:94:56

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit

Replies are listed 'Best First'.
Re^2: Help me decipher code containing map function
by adamZ88 (Beadle) on May 23, 2017 at 14:33 UTC

    Browser, I very much prefer your method of unpacking the MAC. I have implemented it into my code. Thank you for taking the time to explain. Now I am doubting everything I learned in class :/. I have an additional question, can I compare a packed MAC just as I can compare it after unpacked? like:

    if($packed1 eq $packed2){ print "The packed MACs match\n"; else{ print "The packed MACs do not match\n"; }
      can I compare a packed MAC just as I can compare it after unpacked?

      Yes. Before you unpack and format them, your octet strings are just sequences of bytes with binary values in the range 0 -> 255. Ie. strings. Perl's normal string comparison operations (eq, ne, lt, le, gt, ge) will work perfectly on them; and you can use cmp to sort them.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
      In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit

        Excellent, that is the answer I was looking for. Thanks.

      I will take the liberty of answering for BrowserUk. I'm not sure what $packed1 and $packed2 are supposed to represent. If $packed1 is the original, raw MAC address and $packed2 is the reformatted address (with bytes represented as hex-digit pairs and with dots thrown in for good measure), then no, they cannot be directly compared:

      c:\@Work\Perl\monks>perl -wMstrict -le "my $octetstr = qq{\x44\x69\x66\x66\x65\x72}; print qq{raw: '$octetstr'}; ;; my $mac = join '.', unpack '(H4)*', $octetstr; print qq{reformatted: '$mac'}; ;; if ($octetstr eq $mac) { print qq{'$octetstr' and '$mac' are equal}; } else { print qq{'$octetstr' and '$mac' are NOT equal}; } " raw: 'Differ' reformatted: '4469.6666.6572' 'Differ' and '4469.6666.6572' are NOT equal
      (The two strings would have to be converted to a common format for comparison.)

      If $packed1 and $packed2 are both reformatted MAC addresses (and they've both been reformatted according to the same scheme), then yes, they can be directly compared for equality.

      Incidentally, this is another question that's open to resolution by direct experimentation. Could you not have written a couple of short routines to answer your own question — plus some variations?


      Give a man a fish:  <%-{-{-{-<

Re^2: Help me decipher code containing map function
by Anonymous Monk on May 20, 2017 at 19:45 UTC
    why (H2)* and not H* ?

      Because  H* gives you a single string of an unlimited number, necessarily even, of hex characters, but  (H2)* gives you an unlimited number of groups of pairs (or in the case of  (H4)* quartets). The parentheses do grouping in pack/unpack templates. The groups can be quantified. BTW: This is susceptible to experimentation:

      c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my $octetstr = qq{\xab\xcd\x00\x1d\x94\x56}; ;; my @ra = unpack 'H*', $octetstr; dd \@ra; ;; @ra = unpack '(H2)*', $octetstr; dd \@ra; ;; @ra = unpack '(H4)*', $octetstr; dd \@ra; " ["abcd001d9456"] ["ab", "cd", "00", "1d", 94, 56] ["abcd", "001d", 9456]


      Give a man a fish:  <%-{-{-{-<

      Because an even number of hex digits (H) is needed.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Because bytes (pompously aka. octets) consist of 2 hex digits dec:0 -> 0x00 dec:255 -> 0xff.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
      In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit

        The octet term is commonly used in networking, RFC's, etc. It designates an 8-bit unit.

        A byte is generally 8 bits, too, although some historical computers had 9-bit bytes (and 36-bit words). There might be some uses for wide character definition today as well, as there are architectures where memory is word-addressable.

        I suppose the writers of standards and documentation prefer not to get sidetracked with moot issues in terminology, hence the unambiguous "octet".

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (7)
As of 2024-04-24 10:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found