http://qs321.pair.com?node_id=459473

imperl has asked for the wisdom of the Perl Monks concerning the following question:

Hi I'm trying to get the following output: 00:00:00:00:00:01 00:00:00:00:00:02 etc upto 99, then once the last 2 digits reach 99, I want the next 2 numbers to increment: 00:00:00:00:01:99 00:00:00:00:02:99 etc till all the 6 set of numbers are incremented. I tried using for loops but it gets too complicated. Any easier way out?

Replies are listed 'Best First'.
Re: How to increment a MAC Address?
by Forsaken (Friar) on May 23, 2005 at 09:15 UTC
    my way to tackle this would be to split the 6 groups of digits using my @numbers = split(/:/, $string); after which you can access each of the sets as $numbers[0] through to $numbers[5]. Whenever you need them back in string form you can put it back together using join(':', @numbers);

    Now the real question is, last time I checked MAC addresses were in hexadecimal, so you're still in need of ABCDEF on top of the 0 through 9? Besides that, why would you want to iterate through every possible MAC address in the first place?


    Remember rule one...
      To increment a MAC Address, you need to convert HEX to DEC, Add AND convert DEC to HEX...

      I propose this code.

      sub addmac { my ( $mac, $add ) = @_; $mac =~ s/://g; my $dec = hex($mac); $mac = sprintf("%012x", $dec+$add); return join(":", $mac =~ /(..)/g ); } my $mac = '00:00:00:00:00:f1'; foreach ( 1 .. 32 ) { $mac = addmac($mac,$_*4); print "$mac\n"; }
      I think others improve are possible, but it do a task.
      ... 00:00:00:00:01:a5 00:00:00:00:01:cd 00:00:00:00:01:f9 00:00:00:00:02:29 00:00:00:00:02:5d ... 00:00:00:00:03:9d 00:00:00:00:03:e9 00:00:00:00:04:39 00:00:00:00:04:8d

      --
      Marco Antonio
      Rio-PM

        Close, but not quite. You're trying to store a 48bit number into a 32bit variable. (Well, it's 32 bit on my Windows machine.) You have an overflow problem.

        my $dec = hex('FF0000000000'); printf("%012x", $dec); __END__ Integer overflow in hexadecimal number at !.pl line 1 0000ffffffff

        You could use Math::BigInt, or you could use floating point numbers (doubles) as I've previously detailed.

      You code prints: 00:00:00:00:00:99 00:00:00:00:01:00 00:00:00:00:01:01 OP wants: 00:00:00:00:00:99 00:00:00:00:01:99 00:00:00:00:02:99 and so on. Note: Once the pair of digit reaches 99, it does not roll back to 00.
Re: How to increment a MAC Address?
by dorward (Curate) on May 23, 2005 at 09:19 UTC

    Something like this perhaps?

    $" = ':'; for (my $int = 1; $int <= 999999999999; $int++) { my $leading = sprintf("%012d", $int); my @split = ($leading =~ /../g); print "@split\n"; }
      The components of a MAC address, when expressed as a group of six octet values, are expressed as hexadecimal values (eg. FE:DC:BA:01:23:45) - Your code does not account for this with the maximal octet value of 99 (decimal) provided by your code.

      Although in stating this, I should note that this is a problem too with the problem description in the original thread post.

       

      perl -le "print unpack'N', pack'B32', '00000000000000000000001000000000'"

        yes, i know 99 is not valid, just that im simulating something out here, where i require the value as 99 and not in hex.
      You code prints:
      00:00:00:00:00:99
      00:00:00:00:01:00
      00:00:00:00:01:01


      OP wants:
      00:00:00:00:00:99
      00:00:00:00:01:99
      00:00:00:00:02:99 and so on.

      Note: Once the pair of digit reaches 99, it does not roll back to 00.

        I've just tested it and it increments as expected (i.e. it does get past 1).

Re: How to increment a MAC Address?
by zengargoyle (Deacon) on May 24, 2005 at 18:36 UTC
    #!/usr/bin/perl use strict; use warnings; my @wheels = (0) x 6; sub collapse { join ':', map { sprintf "%02d", $_ } @wheels; } sub emit { print collapse(), "\n"; } for my $round ( reverse 0..5 ) { for my $range ( 1..99 ) { $wheels[$round] = $range; emit(); } } __END__ $ ./459473.pl | head 00:00:00:00:00:01 00:00:00:00:00:02 00:00:00:00:00:03 00:00:00:00:00:04 00:00:00:00:00:05 00:00:00:00:00:06 00:00:00:00:00:07 00:00:00:00:00:08 00:00:00:00:00:09 00:00:00:00:00:10 $ ./459473.pl | head -n 105 | tail 00:00:00:00:00:96 00:00:00:00:00:97 00:00:00:00:00:98 00:00:00:00:00:99 00:00:00:00:01:99 00:00:00:00:02:99 00:00:00:00:03:99 00:00:00:00:04:99 00:00:00:00:05:99 00:00:00:00:06:99 $ ./459473.pl | head -n 205 | tail 00:00:00:00:97:99 00:00:00:00:98:99 00:00:00:00:99:99 00:00:00:01:99:99 00:00:00:02:99:99 00:00:00:03:99:99 00:00:00:04:99:99 00:00:00:05:99:99 00:00:00:06:99:99 00:00:00:07:99:99 $ ./459473.pl | tail 90:99:99:99:99:99 91:99:99:99:99:99 92:99:99:99:99:99 93:99:99:99:99:99 94:99:99:99:99:99 95:99:99:99:99:99 96:99:99:99:99:99 97:99:99:99:99:99 98:99:99:99:99:99 99:99:99:99:99:99
Re: How to increment a MAC Address?
by Rhose (Priest) on Jun 16, 2005 at 14:28 UTC
    I missed this thread earlier, and the approach I took is pretty similar to zengargoyle's.

    #!/usr/bin/perl use strict; use warnings; #use constant MAX_VAL => 255; use constant MAX_VAL => 99; my @MAC=(0) x 6; sub PrintMAC { # print join(':',map {sprintf('%02X',$_)} @_),"\n"; print join(':',map {sprintf('%02D',$_)} @_),"\n"; } my $CurNO = 5; while ($CurNO >= 0) { while ($MAC[$CurNO] < MAX_VAL) { PrintMAC(@MAC); $MAC[$CurNO]++; } $CurNO--; } PrintMAC(@MAC);

    On a side note... if you uncomment the two commented lines and comment out the lines immediately below them, you'll get addresses in the full range.

      Here i using the code for increment MAC address of last bit after increment last bit overflow so to over come again recount from starting eg: last position is FF then after we increment by 1 we start count by 00 ----------------
      #!/bin/sh mac=$(ifconfig eth0|grep HWaddr|awk '{print $5}'| tr '[a-z]' '[A-Z]' | + cut -d ':' -f1-5) maclast=$(ifconfig eth0|grep HWaddr|awk '{print $5}'| tr '[a-z]' '[A-Z +]' | cut -d ':' -f6) echo "Mac address= $mac:$maclast" decmac=$(echo "ibase=16; $maclast"|bc) if [ $decmac -eq '241' ] then macinc='00' else incout=`expr $decmac + 1 ` macinc=$(echo "obase=16; $incout"|bc) fi echo "Mac address= $mac:$macinc"
      OUTPUT:
      Mac address= 00:19:D1:F6:F7:F1 Mac address= 00:19:D1:F6:F7:00
Re: How to increment a MAC Address?
by jcoxen (Deacon) on May 24, 2005 at 20:35 UTC
    Here's a brute force approach...

    #!/usr/bin/perl use strict; use warnings; my %hash = ("1" => "00", "2" => "00", "3" => "00", "4" => "00", "5" => + "00", "6" => "00"); for (my $segment = 6; $segment != 0; $segment--) { for (0..99) { $_ = "0$_" if $_ < 10; $hash{$segment} = $_; print "$hash{1}:$hash{2}:$hash{3}:$hash{4}:$hash{5}:$hash{6}\n +"; } }

    Jack