Build an array with a range of MAC addresses [clos

2020-04-27 03:57发布

问题:


Want to improve this question? Update the question so it's on-topic for Stack Overflow.

Closed 4 years ago.

I want to build an array which contains a full list of MAC addresses based on 3 variables: a prefix, a start, and an end.

Let's say I have 20:1E:50:3F:8A as a prefix, 3E as a start, and 43 as an end. This should generate the following array of MAC addresses:

20:1E:50:3F:8A:3E
20:1E:50:3F:8A:3F
20:1E:50:3F:8A:40
20:1E:50:3F:8A:41
20:1E:50:3F:8A:42
20:1E:50:3F:8A:43

I made a start, but it doesn't do the job just yet, and I can't get my head around it:

function generate($prefix, $start, $end){

    $start = str_split($start);
    $end = str_split($end);

    $start_first = $start[0];
    $start_second = $start[1];

    $end_first = $end[0];
    $end_second = $end[1];

    if(is_numeric($start_second)){
        $start_second_numeric = true;
    }
    else{
        $start_second_numeric = false;
    }

    if(is_numeric($end_second)){
        $end_second_numeric = true;
    }
    else{
        $end_second_numeric = false;
    }

    $mac_array = array();

    $range_first = range($start_first, $end_first);

    foreach($range_first as $first_character){

        if($start_second_numeric && $end_second_numeric || !$start_second_numeric && !$end_second_numeric){
            $range_second = range($start_second, $end_second);
        }
        elseif(!$start_second_numeric && $end_second_numeric){
            $range_second = range($start_second, "F");
            $range_third = range("0", $end_second);
        }
        elseif($start_second_numeric && !$end_second_numeric){
            $range_second = range($start_second, "9");
            $range_third = range("A", $end_second);
        }

        foreach($range_second as $second_character){
            $string = $prefix . ":" . $first_character . $second_character;
            array_push($mac_array, $string);
        }

        if(is_array($range_third)){
            foreach($range_third as $second_character){
                $string = $prefix . ":" . $first_character . $second_character;
                array_push($mac_array, $string);
            }
        }

    }

    return $mac_array;
}

Can someone help me out?

回答1:

Running the range should be very easy, assuming you are using a 64bit capable PHP:

$mac_array = range(0x201E503F8A3E, 0x201E503F8A43);
foreach ($mac_array as $mac) {
    echo wordwrap(sprintf("%012X", $mac), 2, ":", true);
}

Now what is going on here?

The range() function creates an array containing integer numbers from the first to the second parameter (if you want to change the steps between, use the optional third parameter).

I use the hexadecimal writing of the numbers, and that's also the reason this is limited to 64bit PHP, because the MAC addresses are longer than 32 bits, 48 bits to be precise.

foreach iterates over that integer array.

Now for every integer, some formatting goes on. sprintf() is useful to format strings - in this case, I want it to print a hexadecimal number with at least 12 digits, and fill them with zeroes. That's what the string "%012X" does.

wordwrap() is a function that splits strings into smaller units with linking characters, by default splits a string into several lines of 75 characters or less, linking with newlines. I abuse it here a bit to split the hexadecimal number into units of 2 characters, and linking them with a colon.

All this is build into PHP already, and should be used. :)



回答2:

This will help with the hex part:

public String[] range (String hexStart, String hexEnd)
{
    int start = Long.parseLong(hexStart, 16);
    int end = Long.parseLong(hexEnd, 16);
    String array[] = new String[end-start];

    for(int i = start; i < end; i++)
    {
        array[i] = Integer.valueOf(String.valueOf(i), 16);
    }

    return array;
}