Kiểm tra xem UUID có hợp lệ không mà không sử dụng biểu thức chính


44

Đưa ra một đầu vào chuỗi, viết chương trình in giá trị trung thực thành STDOUT hoặc tương đương nếu đầu vào là UUID hợp lệ, không sử dụng biểu thức chính quy.

Một UUID hợp lệ là

32 chữ số thập lục phân, được hiển thị trong năm nhóm được phân tách bằng dấu gạch nối, ở dạng 8-4-4-4-12 với tổng số 36 ký tự (32 ký tự chữ và số và bốn dấu gạch nối).

Nguồn

Các trường hợp thử nghiệm

0FCE98AC-1326-4C79-8EBC-94908DA8B034
    => true
00000000-0000-0000-0000-000000000000
    => true
0fce98ac-1326-4c79-8ebc-94908da8b034
    => true
0FCE98ac-1326-4c79-8EBC-94908da8B034
    => true

{0FCE98AC-1326-4C79-8EBC-94908DA8B034}
    => false (the input is wrapped in brackets)
0GCE98AC-1326-4C79-8EBC-94908DA8B034
    => false (there is a G in the input)
0FCE98AC 1326-4C79-8EBC-94908DA8B034
    => false (there is a space in the input)
0FCE98AC-13264C79-8EBC-94908DA8B034
    => false (the input is missing a hyphen)
0FCE98AC-13264-C79-8EBC-94908DA8B034
    => false (the input has a hyphen in the wrong place)
0FCE98ACD-1326-4C79-8EBC-94908DA8B034
    => false (one of the groups is too long)
0FCE98AC-1326-4C79-8EBC-94908DA8B034-
    => false (has a trailing hyphen)
0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
    => false (too many groups)
0FCE98AC13264C798EBC94908DA8B034
    => false (there is no grouping)

Quy tắc

  • Biểu thức thông thường không được phép
  • Phù hợp với mẫu chữ giống như regex không được phép. Ví dụ: sử dụng [0-9a-fA-F]hoặc các số nhận dạng thập lục phân khác (chúng tôi sẽ gọi cái này n) và sau đó khớp nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnnhoặc n[8]-n[4]-n[4]-n[4]-n[12]không được phép
  • Đầu vào có thể được lấy từ STDINhoặc làm đối số cho hàm
  • Đầu vào không phân biệt chữ hoa chữ thường
  • Sẽ an toàn khi giả định rằng đầu vào sẽ không chứa nguồn cấp dữ liệu hoặc dòng mới.
  • Đầu vào có thể chứa bất kỳ ký tự ASCII có thể in nào (bao gồm khoảng trắng)
  • Một giá trị truthy phải được in để STDOUThoặc tương đương nếu đầu vào là một uuid hợp lệ
  • Một giá trị falsey phải được in để STDOUThoặc tương đương nếu đầu vào là không một uuid hợp lệ
  • Nếu sử dụng hàm, thay vì sử dụng STDOUT, đầu ra có thể là giá trị trả về của hàm
  • Giá trị trung thực / falsey không thể được in ra STDERR.
  • Áp dụng sơ hở tiêu chuẩn
  • Đây là , vì vậy chương trình ngắn nhất tính bằng byte sẽ thắng. Chúc may mắn!

Bảng xếp hạng

Đây là một Snippet Stack tạo ra cả bảng xếp hạng và tổng quan về người chiến thắng theo ngôn ngữ.

Để đảm bảo câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề bằng cách sử dụng mẫu Markdown sau

## Language Name, N bytes

Trong đó N là kích thước, tính bằng byte, của trình của bạn

Nếu bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vượt qua các điểm số cũ hoặc bao gồm các cờ trong số byte), chỉ cần đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề của bạn

## Language Name, <s>K</s> X + 2 = N bytes


32
Võng mạc kém . D:
BrainSteel


8
Chỉ để tham khảo, tôi có thể đưa ra giải pháp Retina 28 byte. (Vì vậy, không phải là một lợi thế điên rồ so với các ngôn ngữ chơi gôn mặc dù hiện tại nó sẽ dẫn đầu.)
Martin Ender

5
Các mẫu của Lua có được phép không? Chúng chắc chắn không phải là biểu thức chính quy.
manatwork

1
@JacobKrall Tôi khá chắc chắn rằng nó "giả" cho tất cả các câu hỏi của bạn. Tôi nghĩ rằng thách thức khá rõ ràng rằng chỉ các chuỗi có dạng \h{8}-\h{4}-\h{4}-\h{4}-\h{12}(trong đó \hlà một chữ số thập lục phân) là hợp lệ.
Martin Ender

Câu trả lời:


15

CJam, 31 30 29 byte

8 4__C]Nf*'-*qA,s'G,_el^+Ner=

Chạy tất cả các trường hợp thử nghiệm ở đây.

Giải trình

Thay vì mẫu khớp trực tiếp với đầu vào, trước tiên chúng ta chuyển đổi nó thành một dạng đơn giản hơn có thể dễ dàng so sánh với một chuỗi mẫu đơn.

8 4__C] e# Push the array of segment lengths, [8 4 4 4 12].
Nf*     e# Turn that into strings of linefeeds of the given length.
'-*     e# Join them by hyphens, giving "NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN".
q       e# Read the input.
A,s     e# Push the string "0123456789".
'G,_el^ e# Push the string "ABCDEFabcdef".
+       e# Concatenate the two strings.
N       e# Push a linefeed.
er      e# Replace all hexadecimal digits with linefeeds.
=       e# Check for equality with the pattern string.

23

JavaScript ES6, 73 55 56 ký tự

s=>s.split`-`.map(x=>x.length+`0x${x}0`*0)=="8,4,4,4,12"

Phiên bản 55 ký tự trước có vấn đề với dấu cách trong nhóm:

s=>s.split`-`.map(x=>x.length+("0x"+x)*0)=="8,4,4,4,12"
// "00000000-0000-0000-000 -000000000000" true

Kiểm tra:

f=s=>s.split`-`.map(x=>x.length+`0x${x}0`*0)=="8,4,4,4,12"
;`0FCE98AC-1326-4C79-8EBC-94908DA8B034
0fce98ac-1326-4c79-8ebc-94908da8b034
0FCE98ac-1326-4c79-8EBC-94908da8B034
0GCE98AC-1326-4C79-8EBC-94908DA8B034
0FCE98AC-13264C79-8EBC-94908DA8B034
0FCE98AC-13264-C79-8EBC-94908DA8B034
0FCE98ACD-1326-4C79-8EBC-94908DA8B034
0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
00000000-0000-0000-0000-000000000000
D293DBB2-0801-4E60-9141-78EAB0E298FF
0FCE98AC-1326-4C79-8EBC-94908DA8B034-
00000000-0000-0000-000 -000000000000`.split(/\n/g).every(s=>f(s)==/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i.test(s))

Tuyệt vời (và héo cho tôi) +1
edc65

@ edc65, ý của bạn là "héo" là gì?
Qwertiy

Lạm dụng tuyệt vời của việc chọn ẩn +1
Downgoat

4
khinh bỉ, khinh miệt, khinh bỉ, châm chích, tàn phá, sỉ nhục,
đày đọa

11

PowerShell, 29 21 84 49 37 byte

param($g)@{36=$g-as[guid]}[$g.length]

Rất cám ơn những người trong các ý kiến ​​hỗ trợ cho việc chơi golf này để theo kịp các quy tắc thay đổi - TessellatingHeckler , iFreilicht , Jacob KrallJoey . Vui lòng xem lịch sử chỉnh sửa để sửa đổi và các phiên bản cũ hơn.

Bản sửa đổi này lấy đầu vào là $g, sau đó tạo bảng băm mới @{}với một phần tử, chỉ mục 36được đặt bằng $g-as[guid]. Điều này sử dụng -astoán tử tích hợp để thử chuyển đổi giữa hai loại dữ liệu .NET - từ [string]sang [guid]. Nếu chuyển đổi thành công, một [guid]đối tượng được trả về, khác $nullđược trả lại. Phần này đảm bảo rằng chuỗi đầu vào là .NET GUID hợp lệ.

Bước tiếp theo là lập chỉ mục vào bảng băm với [$g.length]. Nếu $gkhông có độ dài chính xác 36 ký tự, bảng băm sẽ trả về $null, sẽ là đầu ra dưới dạng giá trị falsey. Nếu $gcó độ dài 36 ký tự thì kết quả của lệnh gọi .NET sẽ là đầu ra. Nếu $gkhông phải là .NET GUID hợp lệ (dưới bất kỳ hình thức nào), thì nó sẽ xuất ra $nulldưới dạng giá trị falsey. Mặt khác, nó sẽ xuất ra một đối tượng .NET GUID dưới dạng giá trị trung thực - cách duy nhất có thể là đầu ra là nếu nó phù hợp với định dạng được yêu cầu của thử thách.

Ví dụ

Ở đây tôi gói gọn các lệnh gọi kịch bản trong parens và rõ ràng là một Boolean cho rõ ràng.

PS C:\Tools\Scripts\golfing> [bool](.\check-if-a-uuid-is-valid.ps1 '0FCE98AC-1326-4C79-8EBC-94908DA8B034')
True

PS C:\Tools\Scripts\golfing> [bool](.\check-if-a-uuid-is-valid.ps1 '0FCE98AC-1326-4C79-8EBC-94908DA8B034D')
False

PS C:\Tools\Scripts\golfing> [bool](.\check-if-a-uuid-is-valid.ps1 '0FCE98AC13264C798EBC94908DA8B034')
False

4
Tôi sẽ ném !!($args[0]-as[guid])vào 21 byte.
TessellatingHeckler

2
Bạn không thể lưu 4 byte bằng cách bỏ qua !!()? Là các giá trị $NULL[guid]loại trừ lẫn nhau, chúng đủ điều kiện để đại diện cho các giá trị thật và chim ưng, phải không? Dù sao, cách tuyệt vời để chuyển đổi sang boolean, yêu giải pháp!
iFreilicht

@iFreilicht đó là một điểm; nhìn vào bài đăng "sự thật / falsey" được liên kết - tôi đồng ý rằng nó có vẻ hợp lệ.
TessellatingHeckler

1
Giải pháp này không đúng trả về Truecho 0FCE98AC13264C798EBC94908DA8B034, mà không có dấu gạch nối
Jacob Krall

1
@TessellatingHeckler Không, quá tốt để trở thành sự thật. Việc thêm một chữ số, chẳng hạn như 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(thêm D ở cuối) sẽ trả về falsey $TRUE, vì nó chỉ cắt đi chữ số vi phạm và 36 ký tự đầu tiên là hợp lệ.
admBorkBork

9

Emacs Lisp, 236 byte

(lambda(s)(and(eq(string-bytes s)36)(let((l(string-to-list s))(i 0)(h '(8 13 18 23))(v t))(dolist(c l v)(set'v(and v(if(member i h)(and v(eq c 45))(or(and(> c 47)(< c 58))(and(> c 64)(< c 91))(and(> c 96)(< c 123))))))(set'i(+ i 1))))))

Ung dung:

(lambda (s)
  (and (eq (string-bytes s) 36) ; check length
       (let ((l (string-to-list s))
             (i 0)
             ; location of hyphens
             (h '(8 13 18 23))
             (v t))
         (dolist (c l v)
           (set 'v (and v (if (member i h)      ; check if at hyphen position
                              (and v (eq c 45)) ; check if hyphen
                            (or (and (> c 47) (< c 58))      ; check if number
                                (and (> c 64) (< c 91))      ; check if upper case letter
                                (and (> c 96) (< c 123)))))) ; check if lower case letter
           (set 'i (+ i 1)))))) ; increment

8

Do thay đổi quy tắc , câu trả lời này không còn cạnh tranh :(

C, 98

main(a,n){printf("%d",scanf("%8x-%4hx-%4hx-%4hx-%4hx%8x%n%c",&a,&a,&a,&a,&a,&a,&n,&a)==6&&n==36);}

Chủ yếu là khá tự giải thích. Trình %nxác định định dạng cho số lượng byte được đọc cho đến nay, là 36. scanf()trả về số lượng các mục phù hợp, là 6. Cuối cùng %ckhông nên khớp với bất cứ điều gì. Nếu có, sau đó có văn bản theo dõi và scanf()sẽ trả về 7.

Biên dịch với -wđể ngăn chặn các cảnh báo pesky (có một số).


6

JavaScript ES6, 70 83

LƯU Ý thx đến @Qwertiy để tìm lỗi (và đề xuất một số cải tiến và sửa lỗi)

Thx @ CᴏɴᴏʀO'Bʀɪᴇɴ đã lưu 2 byte

Khác 9 byte lưu simplifiying việc kiểm tra chiều dài (cách phức tạp ngắn hơn trong dự thảo đầu tiên, nhưng không phải bây giờ)

u=>u.split`-`.every((h,l,u)=>u[4]&&-`0x${h}1`&&h.length-'40008'[l]==4)

Giải thích

u=>u.split`-` // make an array splitting at '-'
.every( // for every element the following must be true
 (h,l,u)=> // h is the element, l is the index, u is the whole array
 u[4] // element 4 must be present (at least 5 element in array)
 && -`0x${h}1` // element must be a valid hex string with no extraneous blanks (else NaN that is falsy)
 // get requested length from index (8,4,4,4,12 sub 4 to put in 1 char)
 // a 6th elements will be rejected as undefined != 4
 && h.length-'40008'[l]==4// then check element length
)

Kiểm tra đoạn

f=u=>u.split`-`.every((h,l,u)=>u[4]&&-`0x${h}1`&&h.length-'40008'[l]==4)

console.log=x=>O.innerHTML+=x+'\n'

;[
  ['0FCE98AC-1326-4C79-8EBC-94908DA8B034',true],
  ['0fce98ac-1326-4c79-8ebc-94908da8b034',true],
  ['0FCE98ac-1326-4c79-8EBC-94908da8B034',true],
  ['00000000-0000-0000-0000-000000000000', true],
  ['ffffffff-ffff-ffff-ffff-ffffffffffff', true],
  ['0GCE98AC-1326-4C79-8EBC-94908DA8B034',false],
  ['0FCE98AC-13264C79-8EBC-94908DA8B034',false],
  ['0FCE98AC-13264-C79-8EBC-94908DA8B034',false],
  ['0FCE98ACD-1326-4C79-8EBC-94908DA8B034',false],
  ['0FCE98AC-1326-4C79-8EBC',false],
  ['0FCE98AC-1326-4C79-8EBC-94908DA8B034-',false],
  ['00000000-0000-0000-000 -000000000000', false],
  ['0FCE98AC-1326-4C79-8EBC-94908DA8B034-123',false],
].forEach(x=>{
  var t=x[0], r=f(t), k=x[1]
  console.log('Test '+t+' result '+r+(r==k?' ok':' fail'))
})
<pre id=O></pre>


-1-('0x'+h)=>1/('0x'+h)
Qwertiy

Vấn đề tương tự như trong phiên bản trước của tôi: đúng cho00000000-0000-0000-000 -000000000000
Qwertiy

Không. Nhưng bạn đã thêm một bài kiểm tra sai. Không gian hàng đầu không phải là một vấn đề, nhưng theo sau là một chuỗi được cắt bớt khi chuyển đổi thành số. Xem bình luận của tôi ở trên với một bài kiểm tra.
Qwertiy

'00000000-0000-0000-000 -000000000000' bây giờ tôi thấy nó @Qwertiy Tôi đã bỏ lỡ 3 số 0 thay vì 4
edc65

1
@Stefnotch tôi không đồng ý. Bên ngoài everycuộc gọi ulà một chuỗi, không phải là một mảng
edc65

5

Do thay đổi quy tắc , câu trả lời này không còn cạnh tranh :(

Pure Bash (không có tiện ích bên ngoài), 78

printf -vv %8s-%4s-%4s-%4s-%12s
p=${v// /[[:xdigit:]]}
[ "$1" -a ! "${1/$p}" ]

Lấy đầu vào từ dòng lệnh.

  • Việc printfxây dựng chuỗi sau đây - - - -.
  • Các p=dòng biến đổi này để mô hình sau: [[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]-[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]-[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]-[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]-[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]. Lưu ý điều này trông rất nhiều như một biểu thức thông thường. Tuy nhiên, nó không nằm trong bối cảnh này. Nó là một mô hình cho phù hợp với mô hình vỏ . Khái niệm này tương tự như một biểu thức chính quy, nhưng là một cấu trúc (và cú pháp) khác nhau.
  • Dòng cuối cùng kiểm tra nếu
    • đầu vào không trống
    • nếu kéo mẫu ra khỏi chuỗi đầu vào sẽ tạo ra một chuỗi rỗng

Thành ngữ shell, mã trả về 0 biểu thị thành công / TRUE và 1 biểu thị thất bại / FALSE. Mã trả về có thể được kiểm tra echo $?sau khi chạy tập lệnh.


1
Khớp mẫu shell có thể không tuân theo cú pháp của regex, nhưng lớp ký tự chắc chắn sử dụng định nghĩa và cú pháp từ regex POSIX. Dù sao, tùy thuộc vào OP để quyết định xem có chấp nhận được không.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Các biểu thức thông thường có thể bao gồm các lớp ký tự Posix, nhưng tôi không nghĩ rằng ngụ ý rằng bất cứ điều gì sử dụng lớp ký tự Posix đều là biểu thức chính quy. Như một ví dụ khác trcũng sử dụng các lớp ký tự Posix, nhưng không phải là trình phân tích cú pháp regex.
Chấn thương kỹ thuật số

Bạn có thể tắt một vài ký tự bằng cách tránh các dấu ngoặc kép vô dụng, ví dụ như ở định dạng printf.
Jens

Tôi đã cập nhật thử thách để làm rõ - lý do regexes không được phép là để làm cho nó không thể sử dụng các mẫu hex để khớp với uuids
Jojodmo

4

Jolf, 32 byte

Hãy thử nó ở đây!

 eGi'-DN&bH*28=lH.[8,4,4,4,12]S}
 e                               Property "e"very of next object
  Gi'-                           Split i at hyphen
      DN                       } every comparison function
        &                        logical conjugation of next two arguments
         bH*28                   base 16 of H (first arg); is NaN (falsey) if invalid
              =                  equality of next two items
               lH                the length of H (first arg)
                 .            S  the Sth (index) member of the object inbetween
                  [8,4,4,4,12]   array of lengths

Do một lỗi trong mã của tôi, nó dài hơn mức cần thiết. :( [8,4,4,4,12] nên giống như {8444*26}, nhưng }cũng là đóng hàm: P


2
Vì vậy, nó dài hơn nó phải là bởi vì bạn có các lệnh mơ hồ trong ngôn ngữ bạn tạo ra? : P
Rɪᴋᴇʀ

@RikerW Lỗi ngữ nghĩa nhỏ. Nó được sửa chữa ngay bây giờ.
Conor O'Brien

4

MATL , 55 byte

jttn36=?[9,5,5,5]XsXK)45=?36:Km~)4Y2'A':'F'hm?}F]]]N~1$

Tôi đã kiềm chế sử dụng Ybhàm ( strsplit) vì nó hơi giống với regexp(..., 'split'). Điều này chỉ sử dụng lập chỉ mục và so sánh nhân vật.

Thí dụ

>> matl
 > jttn36=?[9,5,5,5]XsXK)45=?36:Km~)4Y2'A':'F'hm?}F]]]N~1$
 > 
> This is a test
0

>> matl
 > jttn36=?[9,5,5,5]XsXK)45=?36:Km~)4Y2'A':'F'hm?}F]]]N~1$
 > 
> D293DBB2-0801-4E60-9141-78EAB0E298FF
1

Giải trình

jt                     % input string, duplicate
tn36=?                 % if length is 36
  [9,5,5,5]XsXK        % build and copy indices of required '-' positions
  )45=?                % if those entries are indeed '-'
    36:Km~)            % logical index of remaining positions
    4Y2'A':'F'h        % allowed chars in those positions
    m?                 % if all those entries are legal: do nothing
    }                  % else
      F                % false value
    ]                  % end
  ]                    % end
]                      % end
N~                     % true if stack is empty
1$                     % display last result only

3

CJam, 52 42 byte

qeu__{A7*)<},\'-/83 3b{)4*}%.{\,=}[1]5*=*=

Hãy thử trực tuyến . Xuất chuỗi gốc nếu đúng, xuất chuỗi trống nếu sai ( điều này được cho phép ).

Giải trình:

qeu__                                      e# Take input, make 2 copies
     {A7*)<},\                             e# Remove invalid characters from first copy
              '-/                          e# Split top of stack on '-
                 83 3b{)4*}%               e# Array of group lengths: [8 4 4 4 12]
                            .{\,=}[1]5*=   e# Compare two arrays, return true if group lengths are correct
                                        *= e# Multiply this value by original string (0 = empty string, 1 = same string)

A7*)<sẽ không xóa nhiều ký tự không hợp lệ, như dấu cách +, ?...
Martin Ender

@ MartinBüttner oh bắn ... Tôi đã không nhận ra rằng, tôi sẽ sửa nó trong vài phút.
GamrCorps

3

Julia, 86 byte

s->(t=split(s,"-");map(length,t)==[8,4,4,4,12]&&all(i->!isnull(tryparse(Int,i,16)),t))

Đây là một hàm ẩn danh chấp nhận một chuỗi và trả về một boolean. Để gọi nó, đặt tên cho nó, vd f=s->....

Ung dung:

function f(s::AbstractString)
    # Split the input into an array on dashes
    t = split(s, "-")

    # Ensure the lengths are appropriate
    ok1 = map(length, t) == [8, 4, 4, 4, 12]

    # Ensure each element is a valid hexadecimal number
    ok2 = all(i -> !isnull(tryparse(Int, i, 16)), t)

    return ok1 && ok2
end

3

C # 196 byte

using System.Linq;class P{bool T(string v){var r=v.Length==36;for(var i=0;i<v.Length;i++)r&=new[]{8,13,18,23}.Any(t=>t==i)?v[i]=='-':v[i]>47&&v[i]<58|v[i]>64&&v[i]<71|v[i]>96&&v[i]<103;return r;}}

Ung dung:

using System.Linq;
class P
{
    public bool T(string v)
    {
        var r = v.Length == 36;
        for (var i = 0; i < v.Length; i++)
            r &= new[] { 8, 13, 18, 23 }.Any(t => t == i) 
                ? v[i] == '-' 
                : v[i] > 47 && v[i] < 58 | v[i] > 64 && v[i] < 71 | v[i] > 96 && v[i] < 103;
        return r;
    }
}

Phương thức Tcó thể được gọi với bất kỳ chuỗi không null nào và sẽ trả về truecho GUID hợp lệ, falsenếu không. Đây là một xác nhận thời gian liên tục; với chi phí của ba ký tự, bạn có thể thoát khỏi phương thức (đổi i < v.Lengththành i < v.Length && r).

Sẽ cố gắng để có được bytecount xuống hơn nữa sau này.

Tôi rõ ràng đã rời khỏi Guid.ParseExactcon đường bởi vì đâu là niềm vui trong đó? Đây là, không có nhiều nỗ lực để đánh gôn xuống hơn nữa trong 86 byte :

using System;class P{bool T(string v){Guid x;return Guid.TryParseExact(v,"D",out x);}}

Ung dung:

using System;
class P
{
    bool T(string v)
    {
        Guid x;
        return Guid.TryParseExact(v, "D", out x);
    }
}

2

Python 2, 99 112 byte

def f(u):
 try:u=u.split()[0];int(u.replace('-',''),16);print[8,4,4,4,12]==map(len,u.split('-'))
 except:print 0

Trên một đầu vào hợp lệ, nó in True. Trên một đầu vào không hợp lệ, nó in Falsehoặc 0, tùy thuộc vào lý do tại sao nó không hợp lệ. False0cả hai đều là chim ưng trong Python.

Chức năng phải kiểm tra 3 điều:

  • Mỗi ký tự không gạch nối là một chữ số hoặc nằm trong ABCDEF
  • Có chính xác 4 dấu gạch nối
  • Có 8 ký tự trước dấu gạch nối đầu tiên, 12 ký tự cuối cùng và 4 giữa hai ký tự khác

Đây là một sự cố để hiển thị cách nó kiểm tra chúng. Nó hơi lỗi thời nhưng tôi đói nên tôi sẽ cập nhật sau.

def f(u):
    try:
        int(u.replace('-',''),16) # Remove all hyphens from the string and parse what's
                                  # left as a base 16 number. Don't do anything with this
                                  # number, but throw an exception if it can't be done.

        return[8,4,4,4,12]==map(len,u.split('-')) # Split the string at each hyphen and
                                                  # get the length of each resulting
                                                  # string. If the lengths == [8,4,4,4,12],
                                                  # there are the right number of groups
                                                  # with the right lengths, so the string
                                                  # is valid.
    except:
        return 0 # The only way to get here is if the string (minus hyphens) couldn't be
                 # parsed as a base 16 int, so there are non-digit, non-ABCDEF characters
                 # and the string is invalid.

Tôi đoán bạn có thể lưu 2 byte nếu bạn thay thế cả hai trường hợp returnbằng print. (Trong trường hợp đó, bạn chắc chắn sẽ muốn có trong Python 2, vì printhoạt động khác với Python 3.)
mathmandan

1
Điều này không hoạt động trong Python 3, vì mapbây giờ trả về một "đối tượng bản đồ", không phải là một danh sách.
Tim Pederick

Điều này không hoạt động trong python 2 (có thể là 3) vì inthàm này cho phép khoảng trắng - 0FCE98ac-1326-4c79-8EBC-94908da8B03với một khoảng trắng ở cuối. Xem bình luận trong câu trả lời Pyth bị xóa ở đây nếu có thể.
Màu xanh

2

Python 2, 57 byte

Cảm ơn lòng tốt cho tích hợp! - đảm bảo kèm theo chuỗi trong dấu ngoặc kép.

import uuid
try:uuid.UUID(input());print 1
except:print 0

5
Theo các tài liệu bạn liên kết đến, nó sẽ in 1cho đầu vào 12345678123456781234567812345678.
Dennis

nếu điều này hoạt động, bạn có thể lưu byte bằng cách thực hiện try:print uuid.UUID(input())bởi vì tất cả những gì cần thiết là bạn in một giá trị trung thực
ngầm trong

2
Chương trình này chấp nhận nhiều định dạng UUID, nhưng câu hỏi chỉ muốn định dạng UUID 36 ký tự, có dấu gạch nối.
Jacob Krall

2
Bạn có thể cứu vãn điều này, đối phó với các quy tắc được cập nhật, bằng cách kiểm tra xem chuỗi đầu vào có bằng uuid được chuyển đổi thành chuỗi không. Cung cấp cho bạn một giá trị trung thực ngay lập tức.
agtoever

2

Bình thường, 39 byte

&&!+1xzd.xi:zK\-k16ZqxKc+zK1mid36"8dinz

Hãy thử nó ở đây .


Liên kết "dùng thử tại đây" của bạn bị thiếu \ký tự K\-k, vì vậy nó không chạy được.
Alex

Điều đó đã được khắc phục ngay bây giờ
Blue

2

Perl 6 ,  83   67 byte

# 83 bytes
{
  (
    my@a=.uc.split('-')
  ).map(*.comb)⊆('0'..'9','A'..'F')
&&
  @a».chars~~(8,4,4,4,12)
}

# 67 bytes
{
  (
    $/=.split('-')
  ).map({:16($_)//|()})==5
&&
  $/».chars~~(8,4,4,4,12)
}

(số lượng không bao gồm dòng mới hoặc thụt lề vì chúng không cần thiết)

sử dụng:

# give it a name
my &code = {...}

say map &code, «
  D293DBB2-0801-4E60-9141-78EAB0E298FF
  0FCE98AC-1326-4C79-8EBC-94908DA8B034
  0fce98ac-1326-4c79-8ebc-94908da8b034
  0FCE98ac-1326-4c79-8EBC-94908da8B034
  00000000-1326-4c79-8EBC-94908da8B034
»;
# (True True True True True)

say map &code, «
  0GCE98AC-1326-4C79-8EBC-94908DA8B034
 '0FCE98AC 1326-4C79-8EBC-94908DA8B034'
  0FCE98AC-13264C79-8EBC-94908DA8B034
  0FCE98AC-13264-C79-8EBC-94908DA8B034
  0FCE98ACD-1326-4C79-8EBC-94908DA8B034
  0FCE98AC-1326-4C79-8EBC-94908DA8B034-
  0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
»;
# (False False False False False False False)

2

Lisp thường gặp - 161

(lambda(s &aux(u(remove #\- s)))(and(=(length s)36)(=(length u)32)(every(lambda(p)(char=(char s p)#\-))'(8 13 18 23))(ignore-errors(parse-integer u :radix 16))))

Giá trị trả về nếu true là hàm băm, dưới dạng số, là kết quả hữu ích cần có.

Ung dung

(defun uuid-p (string &aux (undashed (remove #\- string)))
  (and
   ;; length of input string must be 36
   (= (length string) 36)

   ;; there are exactly 4 dashes
   (= (length undashed) 32)

   ;; We check that we find dashes where expected
   (every (lambda (position)
            (char= (char string position) #\-))
          '(8 13 18 23))

   ;; Finally, we decode the undashed string as a number in base 16,
   ;; but do not throw an exception if this is not possible.
   (ignore-errors
    (parse-integer undashed :radix 16))))

@Jojodmo Vâng, chắc chắn! Cảm ơn
coredump

2

F # 44 ký tự

fun s->System.Guid.TryParseExact(s,"D")|>fst

Trong F #, các hàm với outtham số có thể được gọi bằng cách bỏ tham số out; giá trị của nó khi trả về sẽ được kết hợp với giá trị trả về thực của hàm thành một tuple.

Ở đây, bộ dữ liệu được dẫn đến fsthàm, trả về thành viên đầu tiên của nó, trong trường hợp này là giá trị trả về Boolean của TryPudeExact, biểu thị sự thành công hay thất bại của cuộc gọi.

Để kiểm tra định dạng chính xác, chúng tôi truechỉ trả về nếu chuỗi dài 36 ký tự.

Trước khi tôi thấy câu trả lời C # của RobIII, tôi đã không nghĩ đến việc sử dụng TryPudeExact, vì vậy câu trả lời của tôi là dài hơn ba ký tự:

fun s->System.Guid.TryParse s|>fst&&s.Length=36

TryParse(string, Guid) chấp nhận đầu vào theo các định dạng sau:

00000000000000000000000000000000 
00000000-0000-0000-0000-000000000000 
{00000000-0000-0000-0000-000000000000} 
(00000000-0000-0000-0000-000000000000)
{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}

Trong số này, chỉ có cái thứ hai dài 36 ký tự.


2

Python 2, 93 89 85 byte

lambda u:(set(u)<=set("-0123456789abcdefABCDEF"))*map(len,u.split("-"))==[8,4,4,4,12]

Cuộc map()gọi đảm bảo rằng các phần có độ dài phù hợp và all()kiểm tra từng ký tự xem có phải là dấu gạch nối hoặc chữ số hex trường hợp tùy ý. Biểu thức trình tạo đang kiểm tra từng ký tự bằng cách lặp qua toàn bộ chuỗi đó, vì vậy đây không phải là phương thức hiệu quả nhất, tôi sợ, nhưng nó sẽ đáp ứng các trường hợp thử nghiệm:

>>> f=lambda u:(set(u)<=set("-0123456789abcdefABCDEF"))*map(len,u.split("-"))==[8,4,4,4,12]
>>> testcases = """\
... D293DBB2-0801-4E60-9141-78EAB0E298FF
... 0FCE98AC-1326-4C79-8EBC-94908DA8B034
... 0fce98ac-1326-4c79-8ebc-94908da8b034
... 0FCE98ac-1326-4c79-8EBC-94908da8B034
... 00000000-0000-0000-0000-000000000000""".splitlines()
>>> failcases = """\
... 0GCE98AC-1326-4C79-8EBC-94908DA8B034
... 0FCE98AC 1326-4C79-8EBC-94908DA8B034
... 0FCE98AC-13264C79-8EBC-94908DA8B034
... 0FCE98AC-13264-C79-8EBC-94908DA8B034
... 0FCE98ACD-1326-4C79-8EBC-94908DA8B034
... 0FCE98AC-1326-4C79-8EBC-94908DA8B034-
... 0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
... 00000000-0000-0000-000 -000000000000
... 00000000-0000-0000- 000-000000000000""".splitlines()
>>> all(f(u) for u in testcases)
True
>>> any(f(u) for u in failcases)
False
>>> 

Bất cứ ai cũng có ý tưởng tại sao câu trả lời Python chính xác ngắn nhất đã bị hạ cấp? Không đủ giải thích?
rsandwick3

Jojodmo - trong trường hợp có sự nhầm lẫn về điều này, tôi đã không từ chối thay đổi được đề xuất của bạn - Tôi đã thực hiện chỉnh sửa vì tôi đã bỏ lỡ các ký tự AF (Tôi đã sao chép từ một cửa sổ nơi tôi đang kiểm tra các trường hợp tiêu cực) và Tự động cộng đồng - từ chối đề xuất của bạn mà tôi không biết nó thậm chí đã được nêu ra. Vào thời điểm tôi biết bạn đã đề xuất nó, @nimi đã thực hiện chỉnh sửa cho tiêu đề. Tôi rất hy vọng điều đó không liên quan gì đến downvote, vì điều đó sẽ phản ánh rất kém về cộng đồng này. Dù sao, tôi sẽ cho rằng đó là điều khác, và thêm một chút giải thích.
rsandwick3

2
Bạn có thể xóa f=và khoảng trắng xung quanh chuỗi trong allkhối.
FryAmTheEggman

oh tuyệt vời, thoải mái bắt - sửa
rsandwick3

1
Bạn có thể lưu 8 (hoặc 6, bạn có thể cần thêm dấu ngoặc đơn) bằng cách chuyển đổi all(..)để đặt kiểm tra bao gồm : set(u)<=set("-0123456789abcdefABCDEF").
409_Conflict

1

SÀI GÒN, 171 144 141

data;infile stdin;file stdout;input a$9b$14c$19d$24;e=(a!!b!!c!!d='----')*length(_infile_)=36*(1-missing(put(input(compress(_infile_,,'adk'),$hex32.),$hex32.)));put e;run;

Trên thực tế sử dụng stdin và stdout - một trong những tính năng ít được biết đến của ngôn ngữ đặc biệt này. Làm việc cho các ví dụ cho đến nay, nhưng có thể không phải trong mọi trường hợp. Có lẽ có thể được cải thiện.

Cách tiếp cận tốt hơn - một nhân vật tại một thời điểm:

data;infile stdin;file stdout;do i=1 to 37;input@i c$1.@;a+ifn(i in(9,14,19,24),c='-',n(input(c,hex.))-36*(i>36&c^=''));end;b=a=36;put b;run;

Chơi thêm 6 ký tự ngoài biểu thức trung tâm!

Ung dung:

data;
infile stdin;
file stdout;
do i=1 to 37;
input@i c$1.@;
a+ifn(i in(9,14,19,24),c='-',n(input(c,hex.))-36*(i>36&c^=''));
end;
b=a=36;
put b;
run;

Điều này tạo ra khá nhiều cảnh báo và ghi chú trong nhật ký, nhưng nó không in chúng ra thiết bị xuất chuẩn hoặc thiết bị xuất chuẩn, vì vậy tôi nghĩ đây là trò chơi công bằng.


1

C, 391 byte

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define F printf("0")
#define T printf("1")
#define E return 0
main(){char s[99],*t;int k=1,l,i;scanf("%99[^\n]",s);if(s[strlen(s)-1]=='-'){F;E;}t=strtok(s,"-");while(t!=NULL){for(i=0,l=0;t[i]!=0;i++,l++){if(!isxdigit(t[i])){F;E;}}if((k==1&&l!=8)||((k>1&&k<5)&&l!=4)||(k==5&&l!=12)){F;E;}k++;t=strtok(NULL,"-");}if(k==6){T;E;};F;}

1

MATLAB, 126 byte

function f(a)
b='-';if length(a)==36&&a(9)==b&&a(13)==b&&a(17)==b&&a(21)==b;a(a==b)=[];if any(isnan(hex2dec(a)));0;end;1;end;0

1

Python 3, 134 byte

def a(i):
 try:l=[1+int(k,16)and(len(k)==c)for k,c in zip(i.split("-"),[8,4,4,4,12])];return(len(l)==5)&(0 not in l)
 except:return 0

int (k, 16) cố gắng chuyển k thành int-16 int. Trên một ký tự khác 0-9a-fA-F- nó không thành công, trong trường hợp đó chúng ta trả về 0, đó là giả. Thêm 1 vào int đó và chúng tôi nhận được một giá trị trung thực được đảm bảo - chúng tôi đã loại bỏ tất cả các dấu gạch nối với str.split () để chúng tôi không thể nhận được giá trị -1 và tất cả các số không 0 đều là sự thật.


1

Hàm C, 102

Một thay đổi quy tắc không cho phép scanf()câu trả lời dựa trên c trước đây của tôi , vì vậy đây là một câu trả lời c khác sử dụng isxdigit()mà tôi nghĩ nên được phép cạnh tranh :

i;f(char *s){for(i=8;i<24;i+=5)s[i]=s[i]-45?1:s[i]+3;for(i=0;isxdigit(s[i]);i++);return i==36&&!s[i];}

Hãy thử trực tuyến.

  • Kiểm tra các -ký tự (ASCII 45) tại các vị trí liên quan - nếu vậy, hãy thay thế chúng bằng 0s (ASCII 48 (= 45 + 3))
  • Đi bộ chuỗi kiểm tra từng char với isxdigit()
  • Trả về TRUE nếu độ dài chuỗi là 36 và ký tự cuối cùng là NUL.

1

Hàng loạt, 148 139 + 2 = 150 141 byte

@set/pu=
@for %%d in (1 2 3 4 5 6 7 8 9 A B C D E F)do @set u=!u:%%d=0!
@if -!u!==-00000000-0000-0000-0000-000000000000 exit/b0
@exit/b1

Đã thêm 2 byte vì bạn cần sử dụng /vchuyển sang CMD.EXE.

Thoát với ERRORLEVEL 0 khi thành công, 1 khi thất bại.

Chỉnh sửa: Đã lưu một số byte chủ yếu vì :=không phân biệt chữ hoa chữ thường nhưng cũng có các chỉnh sửa khác.


1

Java, 345 byte

interface q{static void main(String[]a){int i=-1;char[]b=a[0].toCharArray();java.io.PrintStream u=System.out;if(b.length>36||b.length<36)u.print(1<0);if(b[8]!='-'||b[13]!='-'||b[18]!='-'||b[23]!='-')u.print(1<0);while(++i<b.length){if(i!=8&&i!=13&&i!=18&&i!=23){if(!((b[i]>='0'&&b[i]<='F')||(b[i]>='a'&&b[i]<='f')))u.print(1<0);}}u.print(1>0);}}

Đầu vào là đối số dòng lệnh đầu tiên. Đầu ra là mã lỗi (0 có nghĩa là UUID hợp lệ, 1 có nghĩa là không hợp lệ)

Ungolfed với ý kiến:

interface q {
    static void main(String[] a) {
        int i = -1;                                                             // Index
        char[] b = a[0].toCharArray();                                          // Characters from input
        java.io.PrintStream u = System.out;                                     // STDOUT
        if (b.length > 36||b.length < 36)                                       // If input length is not 36
            u.print(1<0);                                                       // Invalid
        if (b[8]!='-'||b[13]!='-'||b[18]!='-'||b[23]!='-')                      // If hasn't got separators at correct positions
            u.print(1<0);                                                       // Invalid
        while (++i<b.length) {                                                  // Iterate over all characters
            if (i!=8 && i!=13 & i!=18 && i!=23) {                               // If not at separator indexes
                if ( !( (b[i]>='0'&&b[i]<='F') || (b[i]>='a'&&b[i]<='f') ))     // If incorrect hexadecimal number
                    u.print(1<0);                                               // Invalid
            }
        }
        u.print(1>0);                                                           // Valid
    }
}

EDIT: Không nhận thấy phần STDOUT. Rất tiếc, đã sửa bây giờ.


Đẹp! Bạn có thể thay thế if(b.length>36||b.length<36)bằng đơn giản if(b.length!=36). Ngoài ra, vì bạn có thể in các giá trị trung thực , bạn chỉ có thể in 0thay vì 1<01thay vì 1>0.
Jojodmo

@Jojodmo Dựa trên các phiếu bầu, một giá trị trung thực ở dạng if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }So trong Java, boolean là một giá trị trung thực, nhưng 1hoặc 0không. Chỉ khi OP của một thách thức nói điều gì đó như: " Đầu ra của bạn có thể đúng / sai, 0/1, trống / không trống; miễn là bạn chỉ định những gì bạn sử dụng. " Thì bạn thực sự có thể sử dụng 01thay vì true/falselà sự thật / giá trị chim ưng.
Kevin Cruijssen

1
Đối với mẹo chơi gôn cho cookie: @Jojodmo thực sự đúng với việc thay thế nó cho if(b.length!=36); ||có thể |ở nhiều nơi, cũng như &&đến &; if(...!='-')có thể được if(...!=45); int i=-1; ... while(++i<b.length){có thể được thay thế bằng for(int i=-1;++i<b.length;){; 'F'có thể là 70( 'f'có thể là 102, nhưng điều đó không thành vấn đề vì nó có cùng số byte). Tôi thích cách bạn đã sử dụng java.io.PrintStream u=System.out;btw, tôi nên nhớ cái đó! Cảm ơn
Kevin Cruijssen

1

Swift 3, 50 byte

Truyền trong một chuỗi s

import Foundation
print(UUID(uuidString:s) != nil)

1

PHP, 109 byte

in 1 cho đúng và 0 cho sai

for($t=($l=strlen($a=$argn))==36;$i<$l;$i++)$t*=$i>7&$i<24&!($i%5-3)?$a[$i]=="-":ctype_xdigit($a[$i]);echo$t;

$i>7&$i<24&!($i%5-3) ngắn hơn 5 byte in_array($i,[8,13,18,23])

112 byte

echo array_filter(str_split($argn),function($i){return!ctype_xdigit($i);})==[8=>"-",13=>"-",18=>"-",23=>"-"]?:0;

113 byte

echo array_diff(str_split(strtolower($argn)),array_map(dechex,range(0,15)))==[8=>"-",13=>"-",18=>"-",23=>"-"]?:0;

0

Java, 172 byte 168 byte (Cảm ơn Wheat Wizard)

Kinda gian lận kể từ khi tôi sử dụng java.util.UUID, nhưng ở đây đi:

import java.util.UUID;class ValidUUID{public static void main(String[] a){try{UUID.fromString(a[0]);System.out.println(1);}catch(Exception e){System.out.println(0);}}}

Phiên bản bị đánh cắp:

import java.util.UUID;

class ValidUUID {

    public static void main(String[] a) {
        try {
            UUID.fromString(a[0]);
            System.out.println(1);
        } catch(Exception e) {System.out.println(0);}
    }
}

Chào mừng đến với trang web! Tôi nghĩ bạn có thể loại bỏ khoảng cách giữa try{.
Phù thủy lúa mì

@WheatWizard cảm ơn bạn: D cũng nhận thấy tôi có thể xóa "khoảng 0 và 1
ryxn

2
Bạn sẽ có thể loại bỏ không gian giữa String[]a. Ngoài ra, bạn sẽ có thể thay thế printlnbằng print.
clismique

1
Tên lớp có thể là 1 ký tự. Bạn có thể sử dụng java.util.UUID.fromStringthay vì nhập khẩu.
Chọc

0

AWK, 98 byte

BEGIN{FS=""}{for(j=4;k<NF;){h+=(j+=5)<25?$j=="-":0
s+=strtonum("0x"$++k 1)>0}$0=h+s==36&&NF==36}1

Đơn giản chỉ cần chia dòng ở mỗi ký tự và kiểm tra xem mỗi ký tự có phải là một chữ số hex hay không và có dấu gạch nối ở những vị trí thích hợp. strtonumchuyển đổi các ký tự không hợp lệ thành 0. Việc so sánh giữa 0m(và ký tự không hợp lệ được chọn tùy ý) yêu cầu các bước bổ sung. May mắn 01là một số hex hợp lệ, nhưng m1không.

Ban đầu tôi đã viết hai forvòng, nhưng tôi đã lưu 1 byte bằng cách ép chúng lại với nhau. :)

LƯU Ý: GAWKcó thể đọc đầu vào dưới dạng số hex, nhưng điều này đòi hỏi tùy chọn dòng lệnh rất dài.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.