นิพจน์ทั่วไปสำหรับที่อยู่ MAC คืออะไร?


คำตอบ:


267

มาตรฐาน (IEEE 802) รูปแบบสำหรับการพิมพ์ MAC-48 ที่อยู่ในรูปแบบที่เป็นมิตรกับมนุษย์เป็นกลุ่มหกของตัวเลขสองหลักเลขฐานสิบหกแยกจากกันโดยยัติภังค์หรือทวิภาค-:

ดังนั้น:

^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$

21
โปรดทราบว่าหากจัดเก็บด้วยอักษรฐานสิบหกตัวพิมพ์เล็กมันจะไม่ตรงกันให้เปลี่ยนกลุ่มเป็น [0-9A-Fa-f] เพื่อจับทั้งสองกรณี
Scott Chamberlain

5
คุณอาจต้องการที่จะไม่สนใจปลอก
dietbuddha

5
^ ([0-9A-Fa-f] {2} [: -]) {5} ([0-9A-Fa-f] {2}) $
Rajavel D

2
นอกจากนี้คำพูดข้างต้นเกี่ยวกับ "รูปแบบมาตรฐาน" มาจาก Wikipedia ไม่ใช่มาตราฐาน 802.3 จริงๆแล้ว IEEE 802-2014 ระบุยัติภังค์สำหรับที่อยู่ MAC ธรรมดา (¶ 8.1 ¶ 3) และเครื่องหมายทวิภาคสำหรับสัญกรณ์บิตย้อนกลับที่ล้าสมัย (¶ 4) ที่สำคัญในทางปฏิบัติไม่มีใครสังเกตนี้ เราเพียงแค่ใช้อย่างใดอย่างหนึ่ง แต่ไม่เคยผสมใน MAC ที่เขียนขึ้นเพียงครั้งเดียว
pilcrow

1
ฉันไม่คิดว่า RegEx นี้ถูกต้องเนื่องจากยังจำแนก '3D-F2-C9: A6-B3: 4F' เป็นที่อยู่ MAC ที่ถูกต้องแม้ว่าจะไม่ถูกต้องก็ตาม สิ่งที่ถูกต้องคือ: ((([a-zA-z0-9] {2} [-:]) {5} ([a-zA-z0-9] {2})) | (([a- zA-z0-9] {2} :) {5} ([a-zA-z0-9] {2}))) ดังนั้นทุกครั้งที่คุณสามารถเลือก ":" หรือ "-" สำหรับที่อยู่ MAC ทั้งหมด
PyFox

23

ยากเล็กน้อยในสายตา แต่สิ่งนี้:

/^(?:[[:xdigit:]]{2}([-:]))(?:[[:xdigit:]]{2}\1){4}[[:xdigit:]]{2}$/

จะบังคับใช้เครื่องหมายทวิภาคทั้งหมดหรือขีดกลางทั้งหมดสำหรับสัญกรณ์ MAC ของคุณ

( A1:B2-C3:D4-E5:F6ตัวอย่างเช่นวิธีการ regex ที่ง่ายกว่าอาจอนุญาตซึ่งวิธีการข้างต้นปฏิเสธ)


วิธีนี้ใช้งานได้ แต่คุณสามารถอธิบายได้ว่า: xdigit คืออะไร? และฉันสังเกตเห็นว่าคุณใส่กลุ่ม ([-:]) หลังความยาวอะไรทำให้ใช้ทั้งเครื่องหมายทวิภาคหรือยัติภังค์?
Xaisoft

2
@Xaisoft, สั้นสำหรับฐานสิบหกบาทมากขึ้นหรือน้อยกว่าวิธีการพูดอีก:xdigit: หมายถึงกลุ่มการจับภาพสำหรับการประแรกหรือลำไส้ใหญ่และมีเพียงตรงกับสิ่งที่จับคู่ว่าเป็นครั้งแรก [a-fA-F0-9]\1([-:])
pilcrow

2
+1 สำหรับใช้ทั้งกลุ่มจับภาพและไม่จับภาพอย่างเหมาะสมและยังใช้สำหรับการใช้งาน:xdigit:(แม้ว่า "ชวเลข" นั้นจะสั้นกว่า[a-fA-F0-9]และเทียบเท่า /[a-f0-9]/iก็สั้นกว่า!)
gb96

@pilcrow คุณช่วยอธิบายได้ไหมว่าทำไม mac นี้: C8:FD:19:55:E6:3Aล้มเหลว? มันเป็นที่อยู่ของ mac จริงๆ ฉันแก้ไข regex ของคุณเพื่อยอมรับ:แต่/^(?:[[:xdigit:]]{2}([:]))(?:[[:xdigit:]]{2}\1){4}[[:xdigit:]]{2}$/ขอบคุณ!
แซม

1
ในใจของฉันนี่เป็นคำตอบที่ดีกว่าเนื่องจากตรวจสอบการใช้ ":" และ "-" แบบผสมกัน
Ray Oei

9

regex นี้ตรงกับ mac ทุกรูปแบบรวมถึงรูปแบบ Cisco เช่น 0102-0304-abcd

^([[:xdigit:]]{2}[:.-]?){5}[[:xdigit:]]{2}$

ตัวอย่างสตริงที่ตรงกับ:

01:02:03:04:ab:cd
01-02-03-04-ab-cd
01.02.03.04.ab.cd
0102-0304-abcd
01020304abcd

รูปแบบผสมจะถูกจับคู่ด้วย!


สิ่งนี้จะจับคู่ตัวคั่นหลังจากอ็อกเต็ตห้าตัวแรกใด ๆ ซึ่งหมายความว่าจะยอมรับaa.aa.bbbb.ccccเป็นต้น
pilcrow

1
#notAllFormatsหากคุณสามารถเข้าถึงระบบ OSX ด้วย WiFi ให้เรียกใช้/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -Iและมองหาบรรทัด BSSID หากอ็อกเต็ตใด ๆ ที่อยู่ต่ำกว่า 0x10 ศูนย์นำหน้าจะหลุด ( %xหรือ%2xแทนที่จะ%02x printfใช้รูปแบบ?)
เมื่อ

8

ตัวคั่น: " : ", " - ", " . "

คู่หรือเดี่ยว: 00 = 0, 0f = f

/^([0-9a-f]{1,2}[\.:-]){5}([0-9a-f]{1,2})$/i

หรือ

/^([0-9a-F]{1,2}[\.:-]){5}([0-9a-F]{1,2})$/


exm: 00:27:0e:2a:b9:aa, 00-27-0E-2A-B9-AA, 0.27.e.2a.b9.aa ...

2
ข้อที่สองจะจับคู่สตริงที่มีอักขระที่ไม่ใช่เลขฐานสิบหกอย่างไม่ถูกต้องเช่น g
Binary Phile

อันที่สองใช้ไม่ได้ในรสชาติส่วนใหญ่ยกเว้น BRE / ERE ซึ่งรองรับการเปรียบเทียบช่วงอักขระ อย่างไรก็ตามการสนับสนุนการจัดเรียงช่วงอักขระจะแตกต่างกันไปตามการนำไปใช้ดังนั้นผลลัพธ์อาจแตกต่างกันไป
nhahtdh

อีกประการหนึ่งคือกลุ่มต่างๆต้องมี 2 ฐานสิบหก
nhahtdh

ในทางทฤษฎีที่อยู่ mac ทั้งหมดที่ส่งคืนโดยโปรแกรมในไวลด์จะเป็นไปตามมาตรฐานเช่นเลขฐานสิบหก 2 หลักในแต่ละกลุ่มแยกกัน อย่างไรก็ตามตัวแปร Unix ที่ไม่ได้มาตรฐานบางตัวจะทำให้เอาต์พุตสั้นลงเมื่อมีศูนย์นำหน้าเหลือเพียง 1 ตัวอักษร hex ในบางกรณี ดังนั้นความต้องการ{1,2}regex
TrinitronX

อย่างไรก็ตามชุดอักขระจาก[0-9a-F]ควรจะเขียนใหม่เป็น:[0-9a-fA-F]
TrinitronX

5

ขอเตือนว่าคุณสมบัติ Unicode \p{xdigit}ประกอบด้วยเวอร์ชัน FULLWIDTH คุณอาจต้องการ\p{ASCII_Hex_Digit}แทน

คำตอบสำหรับคำถามที่ถามอาจเป็นคำตอบที่ดีที่สุด - หากคุณมีโมดูล CPAN ที่น่าเคารพติดตั้งไว้ - โดยพิมพ์:

% perl -MRegexp::Common -lE 'say $RE{net}{MAC}'

ผมแสดงรูปแบบโดยเฉพาะอย่างยิ่งมันจะออกผลลัพธ์ที่นี่เป็นจำนวนรูปแบบโชคดี 13; มีคนอื่น ๆ อีกมากมาย

โปรแกรมนี้:

#!/usr/bin/env perl
use 5.010;
use strict;
use warnings qw<FATAL all>;

my $mac_rx = qr{
    ^ (?&MAC_addr) $
    (?(DEFINE)
        (?<MAC_addr>
                (?&pair) (?<it>  (?&either) )
            (?: (?&pair) \k<it> ) {4}
                (?&pair)
        )
        (?<pair>    [0-9a-f] {2} )
        (?<either>  [:\-]        )
    )
}xi;

while (<DATA>) {
    chomp;
    printf("%-25s %s\n", $_ => /$mac_rx/ ? "ok" : "not ok");
}

__END__
3D:F2:C9:A6:B3:4F
3D:F2:AC9:A6:B3:4F
3D:F2:C9:A6:B3:4F:00
:F2:C9:A6:B3:4F
F2:C9:A6:B3:4F
3d:f2:c9:a6:b3:4f
3D-F2-C9-A6-B3-4F
3D-F2:C9-A6:B3-4F

สร้างผลลัพธ์นี้:

3D:F2:C9:A6:B3:4F         ok
3D:F2:AC9:A6:B3:4F        not ok
3D:F2:C9:A6:B3:4F:00      not ok
:F2:C9:A6:B3:4F           not ok
F2:C9:A6:B3:4F            not ok
3d:f2:c9:a6:b3:4f         ok
3D-F2-C9-A6-B3-4F         ok
3D-F2:C9-A6:B3-4F         not ok

ซึ่งดูเหมือนเป็นสิ่งที่คุณกำลังมองหา



4

ดูคำถามนี้ด้วย

Regexes ดังต่อไปนี้:

^[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}$

^[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}$

1
ไม่มีวิธีทำให้สั้นลงโดยการทำกลุ่มหรือไม่? และฉันจะรวมนิพจน์ทั่วไปเพื่อให้มี a: หรือ a - โดยไม่ต้องแยกนิพจน์ทั่วไป 2 นิพจน์ได้อย่างไร
Xaisoft

รูปแบบย่อที่ netcoder มีให้ก็ใช้ได้เช่นกัน การใช้อย่างใดอย่างหนึ่งอาจขึ้นอยู่กับว่าคุณจำเป็นต้องจับที่อยู่ MAC ใด ๆ หรือเพียงแค่ตรวจสอบความถูกต้องทั้งหมด
JYelton

จำเป็นต้องได้รับการตรวจสอบความถูกต้องทั้งหมดดังนั้นหากมีขีดกลางทั้งหมดหรือเครื่องหมายทวิภาคทั้งหมด หากมีการผสมแสดงว่าไม่ใช่ MAC ที่ถูกต้อง
Xaisoft

2
@Xaisoft: อย่างที่ฉันพูดในความคิดเห็นของคำตอบการผสมเครื่องหมายโคลอนและขีดกลางนั้นถูกต้องตามข้อกำหนด
netcoder

คุณได้รับที่อยู่ MAC จากแหล่งใดซึ่งอาจมีตัวคั่นผสมกัน หากมาจากเครื่องจริง / NIC คุณน่าจะไม่มีปัญหานั้น หากเป็นข้อมูลที่ผู้ใช้ป้อนให้ดำเนินการแทนที่สตริงเพื่อให้ตัวคั่นทั้งหมดสอดคล้องกัน
JYelton



2
/^(([a-fA-F0-9]{2}-){5}[a-fA-F0-9]{2}|([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}|([0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4})?$/

regex ด้านบนตรวจสอบความถูกต้องของที่อยู่ mac ทุกประเภทด้านล่าง:

01-23-45-67-89-ab
01:23:45:67:89:ab
0123.4567.89ab

ฉันคิดว่านี่เป็นสิ่งเดียวที่สมบูรณ์และถูกต้อง
Vincent Sels


1

ขอบคุณ@Mosheมากสำหรับคำตอบที่ดีข้างต้น หลังจากทำการวิจัยเพิ่มเติมแล้วฉันต้องการเพิ่มการค้นพบพิเศษของฉันทั้งในส่วนที่เกี่ยวกับ IEEE 802 และบังคับใช้การใช้ตัวคั่นที่สอดคล้องกันใน regex

มาตรฐาน (IEEE 802) รูปแบบสำหรับการพิมพ์ MAC-48 ที่อยู่ในรูปแบบที่เป็นมิตรกับมนุษย์เป็นกลุ่มหกของตัวเลขสองหลักเลขฐานสิบหกแยกจากกันโดยยัติภังค์ - อย่างไรก็ตามอนุสัญญาที่นำมาใช้กันอย่างแพร่หลายยังอนุญาตให้โคลอน:และสามกลุ่มของเลขฐานสิบหกสี่หลักคั่นด้วยจุด .

เครดิตเต็มไป@Mosheที่นี่สำหรับคำสั่งแรกของเขาและเพื่อ@pilcrowสำหรับการชี้ให้เห็นว่ามาตรฐาน IEEE 802 ครอบคลุมเฉพาะ hypens

นี่คือนิพจน์ทั่วไปที่บังคับให้ใช้ตัวคั่นเดียวกันตลอดที่อยู่ mac:

^(?:(?:[0-9A-Fa-f]{2}(?=([-:]))(?:\1[0-9A-Fa-f]{2}){5}))$

Regex101 สาธิต

และนี่คือส่วนเพิ่มเติมที่อนุญาตให้ใช้โดยไม่มีตัวคั่นเลย:

^(?:(?:[0-9A-Fa-f]{2}(?=([-:]|))(?:\1[0-9A-Fa-f]{2}){5}))$

Regex101 สาธิต


1

ฉันไม่คิดว่า RegEx หลักจะถูกต้องเนื่องจากยังจำแนกประเภท

'3D-F2-C9:A6-B3:4F' 

เป็นที่อยู่ MAC ที่ถูกต้องแม้ว่าจะไม่ถูกต้องก็ตาม สิ่งที่ถูกต้องคือ:

((([a-zA-z0-9]{2}[-:]){5}([a-zA-z0-9]{2}))|(([a-zA-z0-9]{2}:){5}([a-zA-z0-9]{2})))

ดังนั้นทุกครั้งที่คุณสามารถเลือก ':' หรือ '-' สำหรับที่อยู่ MAC ทั้งหมด


0

คุณสามารถใช้ขั้นตอนต่อไปนี้โดยส่งที่อยู่ mac เพื่อตรวจสอบความถูกต้อง

private static final String MAC_PATTERN = "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$";

private boolean validateMAC(final String mac){          
    Pattern pattern = Pattern.compile(MAC_PATTERN);
    Matcher matcher = pattern.matcher(mac);
    return matcher.matches();             
}


0

หากคุณต้องการช่องว่างระหว่างตัวเลขเช่นตัวแปรนี้

3D : F2 : C9 : A6 : B3 : 4F

regex เปลี่ยนเป็น

"^([0-9A-Fa-f]{2}\\s[:-]\\s){5}([0-9A-Fa-f]{2})$"

0

เพื่อให้ตรงกับที่อยู่ MAC EUI-48 และ 64 บิต EUI-64 64 บิต:

/\A\h{2}([:\-]?\h{2}){5}\z|\A\h{2}([:\-]?\h{2}){7}\z/

โดยที่ \ h เป็นอักขระใน [0-9a-fA-F]

หรือ:

/\A[0-9a-fA-F]{2}([:\-]?[0-9a-fA-F]{2}){5}\z|\A[0-9a-fA-F]{2}([:\-]?[0-9a-fA-F]{2}){7}\z/

สิ่งนี้อนุญาตให้ใช้ "-" หรือ ":" หรือไม่มีการใช้ตัวคั่น


0

อาจจะสั้นที่สุด:

/([\da-f]{2}[:-]){5}[\da-f]{2}/i

อัปเดต : มีวิธีที่ดีกว่าในการตรวจสอบที่อยู่ MAC ใน PHP ซึ่งรองรับที่อยู่ MAC ทั้งสไตล์ยัติภังค์และรูปแบบโคลอน ใช้filter_var () :

// Returns $macAddress, if it's a valid MAC address
filter_var($macAddress, FILTER_VALIDATE_MAC);

อย่างที่ฉันรู้มันรองรับที่อยู่ MAC ในรูปแบบเหล่านี้ (x: เลขฐานสิบหก):

xx:xx:xx:xx:xx:xx
xx-xx-xx-xx-xx-xx
xxxx.xxxx.xxxx

0

เนื่องจากที่อยู่ MAC สามารถมีขนาด 6 หรือ 20 ไบต์ (infiniband, ... ) คำตอบที่ถูกต้องคือ:

^([0-9A-Fa-f]{2}:){5}(([0-9A-Fa-f]{2}:){14})?([0-9A-Fa-f]{2})$

คุณสามารถแทนที่: ด้วย [: -.]? ถ้าคุณต้องการตัวคั่นอื่นหรือไม่มีเลย


-1

อันนี้เป็นอันเล็ก:

(([0-9A-F]{2}[:-]?){6})

โปรดทราบว่าการผสมแปลก ๆ ของตัวอักษรหรือตัวคั่นหลายตัวสามารถผ่านได้


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.