如何验证 C 中的字符串是否为有效的 MAC 地址?

发布于 2024-10-14 03:33:33 字数 90 浏览 3 评论 0原文

例子:

12:45:ff:ab:aa:cd    is valid
45:jj:jj:kk:ui>cd    is not valid

example:

12:45:ff:ab:aa:cd    is valid
45:jj:jj:kk:ui>cd    is not valid

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一生独一 2024-10-21 03:33:33

以下代码检查有效的 MAC 地址(带或不带“:”分隔符):

#include <ctype.h>

int isValidMacAddress(const char* mac) {
    int i = 0;
    int s = 0;

    while (*mac) {
       if (isxdigit(*mac)) {
          i++;
       }
       else if (*mac == ':' || *mac == '-') {

          if (i == 0 || i / 2 - 1 != s)
            break;

          ++s;
       }
       else {
           s = -1;
       }


       ++mac;
    }

    return (i == 12 && (s == 5 || s == 0));
}

该代码检查以下内容:

  • 输入字符串 mac 是否恰好包含 12 个十六进制数字。
  • 也就是说,如果分隔符冒号 : 出现在输入字符串中,则它仅出现在偶数个十六进制数字之后。

它的工作原理如下:

  • i,它是mac中的十六进制数字的数量,被初始化为0。
  • while循环遍历mac中的每个字符。输入字符串,直到字符串结束或检测到 12 个十六进制数字。
    • 如果当前字符 (*mac) 是有效的十六进制数字,则 i 递增,并且循环检查下一个字符。
    • 否则,循环检查当前字符是否为分隔符(冒号或破折号);如果是,则验证每对十六进制数字都有一个分隔符。否则,循环将中止。
  • 循环完成后,该函数检查是否找到 12 个十六进制数字以及零个或恰好五个分隔符,并返回结果。

如果您不想接受分隔符,只需将 return 语句更改为:

return (i == 12 && s == 0);

The following code checks for valid MAC addresses (with or w/o the ":" separator):

#include <ctype.h>

int isValidMacAddress(const char* mac) {
    int i = 0;
    int s = 0;

    while (*mac) {
       if (isxdigit(*mac)) {
          i++;
       }
       else if (*mac == ':' || *mac == '-') {

          if (i == 0 || i / 2 - 1 != s)
            break;

          ++s;
       }
       else {
           s = -1;
       }


       ++mac;
    }

    return (i == 12 && (s == 5 || s == 0));
}

The code checks the following:

  • that the input string mac contains exactly 12 hexadecimal digits.
  • that, if a separator colon : appears in the input string, it only appears after an even number of hex digits.

It works like this:

  • i,which is the number of hex digits in mac, is initialized to 0.
  • The while loops over every character in the input string until either the string ends, or 12 hex digits have been detected.
    • If the current character (*mac) is a valid hex digit, then i is incremented, and the loop examines the next character.
    • Otherwise, the loop checks if the current character is a separator (colon or a dash); if so, it verifies that there is one separator for every pair of hex digits. Otherwise, the loop is aborted.
  • After the loop finishes, the function checks if 12 hex digits have been found, and zero or exactly five separators, and returns the result.

If you don't want to accept separators, simply change the return statement to:

return (i == 12 && s == 0);
仅此而已 2024-10-21 03:33:33

我需要验证和解析 ANSI C 中的 MAC 地址,所以这是函数。如果 MAC 地址已通过验证,它将返回 1(它将接受 12 个十六进制字符,小写或大写,带或不带冒号,包括部分正确的输入,如 b3:0a:23:48fad3) 。它在 Cortex m3 控制器上的嵌入式应用程序中为我完成了这项工作。
该函数还将接受来自网页的直接输入(这实际上就是我使用它的方式),因此它将接受冒号作为 %3A 字符。
结果是一个六字节数组。对于此,您必须#include
输入字符串 (*mac) 必须以零结尾才能使函数正常工作。

int parse_mac_address(char* mac, unsigned char *mac_address) {
int index=0;
char temp_mac[12]={0,0,0,0,0,0,0,0,0,0,0,0};

memset(mac_address, 0, 6);              // Clear the 6 needed bytes in target array (which should be defined as "unsigned char mac_address[6]")

while(*mac) {                           // Repeat while we have something in the string
    if(index>11) {                      // The string may be longer than our 12 digits
        return 0;                       // If it has too many digits, break out and return an error (zero)
    }

    if(isxdigit(*mac)) {                // If this is a hex digit
        if(isdigit(*mac)) {             // If the digit is 0 to 9
            temp_mac[index]=*mac-0x30;  // Convert to a number
        }
        else {                          // If the digit is A to F
            temp_mac[index]=toupper(*mac)-0x37; // Make sure it is an upper case letter and convert to a number
        }
        ++mac;                          // Go further on the mac string
        ++index;                        // Promote the index to the next value in our array
    }
    else {
        if(!(index%2) && *mac==':') {   // If it was not a digit, it can be a colon, but only on an odd locations in the array
            ++mac;
        }
        else {
            if(!(index%2) && *mac=='%' && *(mac+1)=='3' && toupper(*(mac+2))=='A') { // In case of web colon sign we receive '%3A' instead, so we have to jump 3 characters to the next digit
                mac+=3; 
            }
            else {                      // If we discovered anything else, this is not a valid mac address - break out and return an error (zero)
                return 0;
            }
        }
    }
}

if(index!=11) {                         // Last check - the index must be exactly 11, to indicate we have filled in 12 digits
    return 0;                           // If not - return with error (zero)
}

for(index=0;index<6;index++) {          // Now, when we have 12 digits in an array, we will convert them in to two-digit bytes
    *(mac_address+5-index)=temp_mac[index*2+1]+temp_mac[index*2]*0x10; // Taking pairs of digits and converting them in to a byte
    // This operation will make mac_address[0] the LSB and mac_address[5] the MSB
    // If you need it the other way round, replace *(mac_address+5-index) with *(mac_address+index)
}

return 1;                               // Return OK (one)
}

I needed to both validate and parse MAC address in ANSI C, so here's the function. It returns 1 in case the mac address has been validated (it will accept 12 hex characters, lower case or upper case, with or without colons, including partially correct input like b3:0a:23:48fad3). It does the job for me in an embedded application on a cortex m3 controller.
The function will also accept direct input from a web page (that's actually how i use it), and therefore it will accept colons as %3A characters.
The result is a six byte array. You will have to #include <cctype> for this one.
The input string (*mac) must be zero-terminated for the function to work.

int parse_mac_address(char* mac, unsigned char *mac_address) {
int index=0;
char temp_mac[12]={0,0,0,0,0,0,0,0,0,0,0,0};

memset(mac_address, 0, 6);              // Clear the 6 needed bytes in target array (which should be defined as "unsigned char mac_address[6]")

while(*mac) {                           // Repeat while we have something in the string
    if(index>11) {                      // The string may be longer than our 12 digits
        return 0;                       // If it has too many digits, break out and return an error (zero)
    }

    if(isxdigit(*mac)) {                // If this is a hex digit
        if(isdigit(*mac)) {             // If the digit is 0 to 9
            temp_mac[index]=*mac-0x30;  // Convert to a number
        }
        else {                          // If the digit is A to F
            temp_mac[index]=toupper(*mac)-0x37; // Make sure it is an upper case letter and convert to a number
        }
        ++mac;                          // Go further on the mac string
        ++index;                        // Promote the index to the next value in our array
    }
    else {
        if(!(index%2) && *mac==':') {   // If it was not a digit, it can be a colon, but only on an odd locations in the array
            ++mac;
        }
        else {
            if(!(index%2) && *mac=='%' && *(mac+1)=='3' && toupper(*(mac+2))=='A') { // In case of web colon sign we receive '%3A' instead, so we have to jump 3 characters to the next digit
                mac+=3; 
            }
            else {                      // If we discovered anything else, this is not a valid mac address - break out and return an error (zero)
                return 0;
            }
        }
    }
}

if(index!=11) {                         // Last check - the index must be exactly 11, to indicate we have filled in 12 digits
    return 0;                           // If not - return with error (zero)
}

for(index=0;index<6;index++) {          // Now, when we have 12 digits in an array, we will convert them in to two-digit bytes
    *(mac_address+5-index)=temp_mac[index*2+1]+temp_mac[index*2]*0x10; // Taking pairs of digits and converting them in to a byte
    // This operation will make mac_address[0] the LSB and mac_address[5] the MSB
    // If you need it the other way round, replace *(mac_address+5-index) with *(mac_address+index)
}

return 1;                               // Return OK (one)
}
最佳男配角 2024-10-21 03:33:33

这是另一个检查 MAC 地址完整性的简单函数

#include <stdio.h>
#include <string.h>

typedef unsigned char byte;

#define ETH_ADDR_LEN    6
#define FALSE           0
#define TRUE            1
#define MAC_STR_LEN     18
#define SEPERATOR       ':'

int isMacValid(char *MacAddress) {
    char mac_part[3] = {0};
    byte mac_byte    = 0;
    byte mac_idx     = 0;

    while(MacAddress[mac_idx] != 0 && mac_idx < MAC_STR_LEN){
        if(mac_idx != 15 && MacAddress[mac_idx + 2] != SEPERATOR)
            return FALSE;
        strncpy(mac_part, MacAddress+mac_idx,2);
        mac_byte = (byte)strtol(mac_part, NULL, 16);
        if(mac_byte == 0 && strcmp(mac_part,"00"))
            return FALSE;
        mac_idx += 3;
    }

    if(mac_idx == MAC_STR_LEN)
        return TRUE;
    return FALSE;
}

Here is another simple function to check sanity of MAC address

#include <stdio.h>
#include <string.h>

typedef unsigned char byte;

#define ETH_ADDR_LEN    6
#define FALSE           0
#define TRUE            1
#define MAC_STR_LEN     18
#define SEPERATOR       ':'

int isMacValid(char *MacAddress) {
    char mac_part[3] = {0};
    byte mac_byte    = 0;
    byte mac_idx     = 0;

    while(MacAddress[mac_idx] != 0 && mac_idx < MAC_STR_LEN){
        if(mac_idx != 15 && MacAddress[mac_idx + 2] != SEPERATOR)
            return FALSE;
        strncpy(mac_part, MacAddress+mac_idx,2);
        mac_byte = (byte)strtol(mac_part, NULL, 16);
        if(mac_byte == 0 && strcmp(mac_part,"00"))
            return FALSE;
        mac_idx += 3;
    }

    if(mac_idx == MAC_STR_LEN)
        return TRUE;
    return FALSE;
}
往日情怀 2024-10-21 03:33:33

您可以依靠 sscanf 检查所提供的 MAC 地址的格式和内容,例如

bool checkMacAddr(const char * mac) noexcept
{
    if(nullptr == mac) return false;
    printf("[%s] strlen(%s)=%lu\n", __func__, mac, strlen(mac));
    if(strlen(mac) != 17) return false;

    uint32_t bytes[6]={0};

    return (6 == sscanf(mac, "%02X:%02X:%02X:%02X:%02X:%02X"
            , &bytes[5]
            , &bytes[4]
            , &bytes[3]
            , &bytes[2]
            , &bytes[1]
            , &bytes[0]));
}

You can rely on the sscanf to check the format and content of the provided MAC address, something like

bool checkMacAddr(const char * mac) noexcept
{
    if(nullptr == mac) return false;
    printf("[%s] strlen(%s)=%lu\n", __func__, mac, strlen(mac));
    if(strlen(mac) != 17) return false;

    uint32_t bytes[6]={0};

    return (6 == sscanf(mac, "%02X:%02X:%02X:%02X:%02X:%02X"
            , &bytes[5]
            , &bytes[4]
            , &bytes[3]
            , &bytes[2]
            , &bytes[1]
            , &bytes[0]));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文