GUID 증가


30

최근 Daily WTF 기사에서 영감을 얻은 ...

GUID ( XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX각 형식의 문자열 , 여기서 각 X는 16 진수를 나타냄)를 사용하여 GUID를 1 씩 증가 시키는 프로그램 또는 함수를 작성하십시오 .

>>> increment_guid('7f128bd4-b0ba-4597-8f35-3a2f2756dfbb')
'7f128bd4-b0ba-4597-8f35-3a2f2756dfbc'
>>> increment_guid('06b86883-f3e7-4f9d-87c5-a047e89a19fa')
'06b86883-f3e7-4f9d-87c5-a047e89a19fb'
>>> increment_guid('89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2cf')
'89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2d0'
>>> increment_guid('89f25f2f-2f7b-4aa6-b9d7-46a98e3cb29f')
'89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2a0'
>>> increment_guid('8e0f9835-4086-406b-b7a4-532da46963ff')
'8e0f9835-4086-406b-b7a4-532da4696400'
>>> increment_guid('7f128bd4-b0ba-4597-ffff-ffffffffffff')
'7f128bd4-b0ba-4598-0000-000000000000'

노트

  • 링크 된 기사와 달리 F로 끝나는 GUID를 증가 시키면 이전 16 진수로 "반드시"이루어져야합니다. 위의 예를 참조하십시오.
  • 입력이 아닌 것으로 가정 할 수 있습니다 ffffffff-ffff-ffff-ffff-ffffffffffff.
  • 9보다 큰 16 진수의 경우 대문자 (AF) 또는 소문자 (af)를 사용할 수 있습니다.
  • 예, GUID는로 시작할 수 있습니다 0.
  • 출력은 필요한 32 진수를 포함 하여 정확히 32 개의 16 진수와 4 개의 하이픈 으로 구성되어야합니다 0.
  • GUID의 버전 번호 나 기타 고정 비트를 유지하지 않아도됩니다. 비트가 특별한 의미를 갖지 않는 128 비트 정수라고 가정하십시오. 마찬가지로 GUID는 Windows GUID구조 의 이진 순서가 아닌 간단한 사전 순서로 정렬한다고 가정합니다 .
  • 함수를 작성하는 경우, 입력은 순서 외 될 수도 char데이터 유형 : string, char[], List<char>, 등을

1
UUIDv4에서 6 개의 고정 비트를 그대로 두어야합니까?
Filip Haglund

2
@FilipHaglund : 아니요. GUID를 128 비트 숫자로 취급하면 특별한 의미가없는 비트가 없습니다. 마찬가지로 GUID는 Windows GUID구조 의 이진 순서가 아닌 간단한 사전 순서로 정렬한다고 가정합니다 .
dan04

3
제안 된 테스트 사례 : 89f25f2f-2f7b-4aa6-b9d7-46a98e3cb29f답변이 전환 될 수 있도록합니다 9 -> a.
Kamil Drakari

1
@dana : 귀하의 언어에 해당하는 C #에 해당하는 모든 데이터 유형을 사용할 수 있습니다 foreach (char ch in theInput).
dan04

답변:


7

05AB1E , 17 15 18 바이트

Kevin Cruijssen 덕분에 2 바이트 절약

'-K1ìH>h¦Ž¦˜S·£'-ý

온라인으로 사용해보십시오! 또는 테스트 스위트

설명

'-K                  # remove "-" from input
   1ì                # prepend a 1 (to preserve leading 0s)
     H               # convert from hex to base 10
      >              # increment
       h             # convert to hex from base 10
        ¦            # remove the extra 1
         ަ˜S·       # push [8, 4, 4, 4, 12]
              £      # split into parts of these sizes
               '-ý   # join on "-"

댕, 당신이 날 이겼어 .. 뭔가 비슷한 것을 가졌지 만 žKÃ대신에 '-K. Btw에서는로 변경 •É]•S3+하여 2 바이트를 절약 할 수 있습니다 ަ˜S·.
Kevin Cruijssen

@ KevinCruijssen : 감사합니다! 내가 Ž지금까지 그 일을 잊어 버린 것을 몇 번이나 잘 모르겠습니다 ...
Emigna

누군가가 0을 선도 할 것이라고 지적했기 때문에이 대답을 받아들이지 않았습니다. 수정하십시오.
dan04

@ dan04 : 좋은 전화! 나는 그것을 생각하지 않았다. 지금 수정해야합니다 :)
Emigna


11

자바 스크립트 (ES6), 85 바이트

출력 문자열은 소문자입니다.

s=>(g=(c,x=+('0x'+s[--n])+!!c)=>1/x?g(x>>4)+(x&15).toString(16):~n?g(c)+'-':'')(n=36)

온라인으로 사용해보십시오!

댓글

s => (                   // s = GUID
  g = (                  // g = recursive function taking:
    c,                   //   c = carry from the previous iteration
    x = +('0x' + s[--n]) //   x = decimal conversion of the current digit
        + !!c            //       add the carry
  ) =>                   //
    1 / x ?              // if x is numeric:
      g(x >> 4) +        //   do a recursive call, using the new carry
      (x & 15)           //   and append the next digit
      .toString(16)      //   converted back to hexadecimal 
    :                    // else:
      ~n ?               //   if n is not equal to -1:
        g(c)             //     do a recursive call, leaving the current carry unchanged
        + '-'            //     and append a hyphen
      :                  //   else:
        ''               //     stop recursion
)(n = 36)                // initial call to g with n = 36 and a truthy carry

5

파이썬 2 , 82 바이트

q='f0123456789abcdef--'
f=lambda s:[str,f][s[-1]in'f-'](s[:-1])+q[q.find(s[-1])+1]

온라인으로 사용해보십시오!

가져 오기 또는 16 진 변환이 없습니다.

문자열 뒤에서 스캔하여 각 문자를 사이클을 따라 이동하면서 자체 0123456789abcdef-이동합니다. f또는 이외의 기호에 -도달하면 왼쪽으로 스캔을 중지하고 나머지는 변경하지 않고 반환합니다. 이 솔루션은 UUID 형식에만 국한되지 않습니다. 16 진수 문자의 수에 제한이 없습니다.

의 기본 사례는 [str,f][s[-1]in'f-'](s[:-1])이전에 골프에서 사용되지 않은 트릭입니다. if, 없이 재귀를 종료합니다 and.or , 또는 기타 명시 적으로 제어 흐름.

[s[-1]in'f-']마지막 문자 의 조건 에 따라 코드는 반환 f(s[:-1])되거나 s[:-1]변경되지 않습니다. str문자열의 아이덴티티 이므로 함수 중 하나를 선택 [str,f]하여에 적용 할 수 s[:-1]있습니다. 와 재귀 호출 f은 선택하지 않으면 수행되지 않으므로 파이썬은 사용하지 않는 옵션을 열심히 평가하여 재귀에서 무한한 회귀를 일으키는 일반적인 문제 문제를 해결합니다.


글쎄, 아침 내 뇌가 간다.
밝게 돈

3

APL (Dyalog Unicode) , 46 바이트 SBCS

익명의 암묵적 접두사 기능.

CY'dfns'
(∊1hex 16(|+1⌽=)⍣≡1+@32dec¨)@('-'≠⊢)

온라인으로 사용해보십시오!

⎕CY'dfns'C의 영업 이익 Y 은 "dfns"라이브러리 (얻을 hexdec )

(... )
 인수
 상이
'-' 대시
(... )@ 위치 이루어진 서브 세트 에서 상기 기준에 해당되는이 적용
dec¨ 십진수 각 진수 문자 변환
 ... @32에서 32 번 위치 (마지막 자리) 적용
  1+ 증가
16(... )⍣≡ 반복적으로 적용 안정 될 때까지 왼쪽 인자 16 :
  = 비교는 (16 진수 16 곳에 마스크 범)
  1⌽ (이 캐리 비트이다) 좌측 순환 회전 한 단계와
  |+ , 그 분할하여 때 (즉 0으로 16하게 여섯 의해) 분할 나머지 추가  회전을 1 자리 16 진수 문자 표현의 숫자 ϵ nlist (flatten)
1hex


3

자바 11 152 149 111 108 바이트

s->{var b=s.getLeastSignificantBits()+1;return new java.util.UUID(s.getMostSignificantBits()+(b==0?1:0),b);}

@ OlivierGrégoire 에게 감사합니다 -38 바이트 .
@ASCII 전용 덕분에 -3 바이트 .

온라인으로 사용해보십시오.

설명:

s->{         // Method with UUID as both parameter and return-type
  var b=s.getLeastSignificantBits()
             //  Get the 64 least significant bits of the input-UUID's 128 bits as long
        +1;  //  And increase it by 1
  return new java.util.UUID(
             //  Return a new UUID with:
    s.getMostSignificantBits()
             //   The 64 most significant bits of the input-UUID's 128 bits as long
    +(b==0?  //    And if the 64 least significant bits + 1 are exactly 0:
       1     //     Increase the 64 most significant bits by 1 as well
      :      //    Else:
       0,    //     Don't change the 64 most significant bits by adding 0
     b);}    //   And the 64 least significant bits + 1

이전 149 바이트 답변 :

s->{var t=new java.math.BigInteger(s.replace("-",""),16);return(t.add(t.ONE).toString(16)).replaceAll("(.{4})".repeat(5)+"(.*)","$1$2-$3-$4-$5-$6");}

온라인으로 사용해보십시오.

설명:

s->{                              // Method with String as both parameter and return-type
  var t=new java.math.BigInteger( //  Create a BigInteger
         s.replace("-",""),       //  Of the input-string with all "-" removed
         16);                     //  Converted from Hexadecimal
  return(t.add(t.ONE)             //  Add 1
         .toString(16))           //  And convert it back to a Hexadecimal String
         .replaceAll("(.{4})".repeat(5)+"(.*)",
                                  //  And split the string into parts of sizes 4,4,4,4,4,rest
           "$1$2-$3-$4-$5-$6");}  //  And insert "-" after parts of size 8,4,4,4,
                                  //  and return it as result


@ OlivierGrégoire 실제 UUID 사용에 대해서는 생각하지 않았습니다! 좋고 짧은 대안. : D
Kevin Cruijssen


-1 대신 long 대신 var 사용
ASCII 전용




2

레티 나 0.8.2 , 21 바이트

T`FfdlL`0dlL`.[-Ff]*$

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 9됩니다 a. 설명 : 정규식은 모든 fs 및 -s와 하나의 선행 문자를 일치시킵니다 . 음역은 문자를 16 진수처럼 주기적으로 증가시킵니다. 대체 방법, 21 바이트 :

T`L`l
T`fo`dl`.[-f]*$

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 음역을 단순화하기 위해 입력을 줄여서 작동합니다. 따라서 소문자 만 지원하면 15 바이트가됩니다. 온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다.


2

MATLAB, 138 바이트

a=1;Z=a;for r=flip(split(input(''),'-'))'
q=r{:};z=dec2hex(hex2dec(q)+a,nnz(q));try
z+q;a=0;catch
z=~q+48;end
Z=[z 45 Z];end;disp(Z(1:36))

청크가 모두 0 인 경우의 버그를 수정했습니다. 또한 try / catch를 학대함으로써 많은 골프를 쳤다. 최종 결과 : 0 바이트가 저장되었습니다.

에서 반환 된 값 이로 변환되어 정밀도 손실이 발생 하여 '치트'를 사용하려는 시도가 java.util.UUID실패했습니다 . 난 당신이 한 번 봐 걸릴 초대 이 테이블 "조용히 완전한를 ...하지만 왜?longjava.util.UUID.get[Most/Least]SignificantBitsdouble "

설명

hex2dec함수는 a를 뱉어 내 double므로 초과하지 않도록 전체 GUID를 한 번에 처리 할 수 ​​없습니다 flintmax. 대신을 사용하여 GUID 청크를 chunck로 처리해야합니다 split. 변수 a는 우리가 하나를 가지고 다닐 필요가 있는지 확인하고 부정적으로 우리가 추가하는 초기 증분입니다. 이월 조건은 원래 문자열과 증가 된 문자열의 길이가 더 이상 같은지 여부입니다.

오리지널 버전은 160 바이트 미만이므로 아웃 고프하기가 쉽지 않다고 생각합니다.



2

C # (Visual C # 대화식 컴파일러) , 77 바이트

x=>{for(int i=35,c;(x[i]=(char)((c=x[i--])<48?c:c==57?65:c>69?48:c+1))<49;);}

온라인으로 사용해보십시오!

@ASCIIOnly 덕분에 -1 바이트!

인수를 수정하여char[] 입력으로 사용하고 출력 하는 익명 함수 .

입력은 오른쪽에서 왼쪽으로 스캔되고 다음 규칙을 사용하여 교체됩니다.

  • -문자는 무시하고 처리가 계속됩니다
  • F문자로 변환됩니다0 and processing continues
  • 9문자로 변환되어 A처리 중지
  • 문자는 A-E0-81 처리를 중지 씩 증가

2
==70->>69
ASCII 전용

우수-감사합니다 :)
dana

2

파워 쉘, 101 바이트

for($p=1;$d=+"$args"[--$i]){$d+=$p*(1-@{45=1;57=-7;70=23;102=55}.$d)
$p*=$d-in45,48
$r=[char]$d+$r}$r

온라인으로 사용해보십시오!

외부 라이브러리 또는 16 진 변환이 없습니다. 모든 문자열 길이 소문자와 대문자가 허용됩니다. 에 일치하는 입력 문자열^[f-]*$ is allowed too.

이 스크립트는 문자열의 뒷면에서 스캔하여 해시 테이블의 값으로 각 문자를 보강합니다.

  • -: 증가율 = 1-1
  • 9: 증분 = 1 + 7, 결과 =A
  • F: 증가 = 1-23, 결과 =0
  • f: 증가 = 1-55, 결과 =0
  • 다른 문자에 대해서는 증가 = 1

다음으로 스크립트는 $p현재 문자를 증가 시킬지 여부를 결정하는 데 사용 합니다.

테스트 스크립트 :

$f = {

for($p=1;$d=+"$args"[--$i]){$d+=$p*(1-@{45=1;57=-7;70=23;102=55}.$d)
$p*=$d-in45,48
$r=[char]$d+$r}$r

}

@(
    ,('f','0')
    ,('F','0')
    ,('0','1')
    ,('9','A')
    ,('A','B')
    ,('a','b')
    ,('0-f','1-0')
    ,('0-F','1-0')
    ,("7f128bd4-b0ba-4597-8f35-3a2f2756dfbb","7f128bd4-b0ba-4597-8f35-3a2f2756dfbc")
    ,("06b86883-f3e7-4f9d-87c5-a047e89a19f9","06b86883-f3e7-4f9d-87c5-a047e89a19fa")
    ,("89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2cf","89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2d0")
    ,("8e0f9835-4086-406b-b7a4-532da46963ff","8e0f9835-4086-406b-b7a4-532da4696400")
    ,("7f128bd4-b0ba-4597-ffff-ffffffffffff","7f128bd4-b0ba-4598-0000-000000000000")
    ,("89f25f2f-2f7b-4aa6-b9d7-46a98e3cb29f","89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2a0")
    ,("ffffffff-ffff-ffff-ffff-ffffffffffff","00000000-0000-0000-0000-000000000000")
) | % {
    $guid,$expected = $_
    $result = &$f $guid
    "$($result-eq$expected): $result"
}

산출:

True: 0
True: 0
True: 1
True: A
True: B
True: b
True: 1-0
True: 1-0
True: 7f128bd4-b0ba-4597-8f35-3a2f2756dfbc
True: 06b86883-f3e7-4f9d-87c5-a047e89a19fA
True: 89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2d0
True: 8e0f9835-4086-406b-b7a4-532da4696400
True: 7f128bd4-b0ba-4598-0000-000000000000
True: 89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2A0
True: 00000000-0000-0000-0000-000000000000



1

PowerShell , 126 바이트

$a=("{0:X32}" -f (1+[Numerics.BigInteger]::Parse($args[0]-replace"-", 'AllowHexSpecifier')));5..2|%{$a=$a.Insert(4*$_,"-")};$a

온라인으로 사용해보십시오!

아주 간단한 답변입니다. 방금 사랑하는 PowerShell을 목록에 추가한다고 생각했습니다. :)



0

Perl 5, 64 bytes

$c=reverse((1+hex s/-//gr)->as_hex);$c=~s/..$//;s/[^-]/chop$c/ge

The number of parentheses necessary here makes me sad, but -> binds very tightly, as ->as_hex is the quickest way I can find to get hexadecimal-formatted output.

Run with perl -Mbigint -p. Basically, it just converts the number to a bigint hexadecimal, adds one, and then subtitutes the digits of the result back into the original value, leaving dashes untouched.


0

Rust, 258 bytes

let x=|s:&str|s.chars().rev().scan(1,|a,c|{let d=c.to_digit(16).unwrap_or(99);match(d,*a){(15,1)=>{*a=1;Some(0)}(0..=14,1)=>{*a = 0;Some(d + 1)}_=> Some(d),}}).collect::<Vec<u32>>().iter().rev().for_each(|d| print!("{}", std::char::from_digit(*d, 16).unwrap_or('-')));

yes its long.. but technically its only one line with 1 expression? and no fancy libraries? and it will not crash on a fuzz input? ungolf:

let x=|s:&str|s.chars().rev().scan(1, |a, c| {
            let d = c.to_digit(16).unwrap_or(99);
            match (d, *a) {
                (15, 1) => {*a = 1;Some(0)}
                (0..=14, 1) => {*a = 0;Some(d + 1)}
                _ => Some(d),
            }
        }).collect::<Vec<u32>>().iter().rev()
        .for_each(|d| print!("{}", std::char::from_digit(*d, 16).unwrap_or('-')));

try it on rust playground



0

16/32/64-bit x86 assembly code, 28 bytes

bytes: 83C623FDAC3C2D74FB403C3A7502B0613C677502B03088460173E9C3

code:

     add esi, 35       ;point to end of string - 1
     std               ;go backwards
l1:  lodsb             ;fetch a character
     cmp al, '-'
     je  l1            ;skip '-'
     inc eax           ;otherwise increment
     cmp al, '9' + 1
     jne l2            ;branch if not out of numbers
     mov al, 'a'       ;otherwise switch '9'+1 to 'a'
l2:  cmp al, 'f' + 1   ;sets carry if less
     jne l3            ;branch if not out of letters
     mov al, '0'       ;otherwise switch 'f'+1 to '0'
                       ;and carry is clear
l3:  mov [esi + 1], al ;replace character
     jnb l1            ;and loop while carry is clear
     ret

Call with ESI pointing to GUID. Replace ESI with SI for 16-bit, or RSI for 64-bit (and +2 bytes).


0

C (clang), 62 bytes

g(char*i){for(i+=36;(*--i-45?*i+=*i-70?*i-57?1:8:-22:0)<49;);}

Try it online!


wait. does the lowercase/uppercase check not cost anything???
ASCII-only

i mean, it can handle both lowercase and uppercase at no cost to bytecount?!
ASCII-only

Ah ok.. ch-70%32 ? : to '0'... 64 and 96 are multiple of 32 so 70-6 and 102-6 %32 .
AZTECCO

1
you don't actually have to handle both, so 64
ASCII-only

0

Common Lisp, 166 bytes

(lambda(s &aux(r(format()"~32,'0x"(1+(parse-integer(remove #\- s):radix 16)))))(format()"~{~a~^-~}"(mapcar(lambda(x y)(subseq r x y))#1='(0 8 12 16 20 32)(cdr #1#))))

Try it online!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.