Erhöhen Sie eine GUID

30

Inspiriert von einem aktuellen Daily WTF-Artikel ...

Schreiben Sie ein Programm oder eine Funktion, die eine GUID (Zeichenfolge im Format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, wobei jedes X eine hexadezimale Ziffer darstellt) und die um eins erhöhte GUID ausgibt.

Beispiele

>>> 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'

Anmerkungen

  • Anders als im verlinkten Artikel muss das Inkrementieren einer GUID, die mit F endet, auf die vorherige Hex-Ziffer übertragen werden. Siehe obige Beispiele.
  • Sie können davon ausgehen, dass die Eingabe nicht sein wird ffffffff-ffff-ffff-ffff-ffffffffffff.
  • Bei Hexadezimalzahlen über 9 können Sie entweder Groß- (AF) oder Kleinbuchstaben (af) eingeben.
  • Ja, GUIDs können mit einem beginnen 0.
  • Ihre Ausgabe muss aus genau 32 Hexadezimalstellen und 4 Bindestrichen im erwarteten Format bestehen, einschließlich aller erforderlichen vorangestellten 0s.
  • Sie müssen die Versionsnummer oder andere feste Bits der GUID nicht beibehalten. Angenommen, es ist nur eine 128-Bit-Ganzzahl, bei der keines der Bits eine besondere Bedeutung hat. In ähnlicher Weise wird angenommen, dass GUIDs in einer einfachen lexikografischen Reihenfolge und nicht in der binären Reihenfolge einer Windows- GUIDStruktur sortiert werden .
  • Wenn eine Funktion schreiben, kann die Eingabe eines beliebigen Sequenz-of- seinen charDatentypen: string, char[], List<char>usw.
dan04
quelle
1
Sollen wir die 6 festen Bits in der UUIDv4 intakt lassen?
Filip Haglund
2
@FilipHaglund: Nein, behandeln Sie die GUID einfach als 128-Bit-Zahl, wobei keines der Bits eine besondere Bedeutung hat. In ähnlicher Weise wird angenommen, dass GUIDs in einer einfachen lexikografischen Reihenfolge und nicht in der binären Reihenfolge einer Windows- GUIDStruktur sortiert werden .
dan04
3
Vorgeschlagener Testfall: 89f25f2f-2f7b-4aa6-b9d7-46a98e3cb29fum sicherzustellen, dass Antworten den Übergang schaffen können 9 -> a.
Kamil Drakari
1
@dana: Sie können jeden Datentyp verwenden, für den die Entsprechung Ihrer Sprache zu C # foreach (char ch in theInput)gültig ist.
dan04

Antworten:

7

05AB1E , 17 15 18 Bytes

2 Bytes dank Kevin Cruijssen gespeichert

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

Probieren Sie es online! oder als Test Suite

Erläuterung

'-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 "-"
Emigna
quelle
Dang, du hast mich geschlagen .. Hatte etwas sehr ähnliches, aber mit žKÃstatt '-K. Btw, können Sie durch Ändern 2 Bytes speichern •É]•S3+zu Ž¦˜S·.
Kevin Cruijssen
@ KevinCruijssen: Danke! Ich weiß nicht, wie oft ich das vergessen Žhabe ...
Emigna
Ich habe diese Antwort nicht akzeptiert, weil jemand darauf hingewiesen hat, dass führende Nullen gelöscht werden. Bitte repariere.
18.
@ dan04: Guter Anruf! Daran hatte ich nicht gedacht. Sollte jetzt behoben sein :)
Emigna
20

Python 2 , 50

  • 3 Bytes gespart dank @Dennis.
lambda s:UUID(int=UUID(s).int+1)
from uuid import*

Probieren Sie es online!

Digitales Trauma
quelle
11

JavaScript (ES6), 85 Byte

Die Ausgabezeichenfolge ist in Kleinbuchstaben.

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

Probieren Sie es online!

Kommentiert

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
Arnauld
quelle
5

Python 2 , 82 Bytes

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

Probieren Sie es online!

Keine Importe oder Hex-Konvertierung.

Dies tastet von der Rückseite der Zeichenkette ab und bewegt jedes Zeichen entlang des Zyklus 0123456789abcdef, wobei -es zu sich selbst geht. Nachdem es ein anderes Symbol als foder getroffen hat -, stoppt es den Scanvorgang nach links und gibt den Rest unverändert zurück. Diese Lösung ist nicht spezifisch für das UUID-Format - eine beliebige Anzahl von Blöcken mit einer beliebigen Anzahl von Hex-Buchstaben würde funktionieren.

Der Grundfall von [str,f][s[-1]in'f-'](s[:-1])ist ein Trick, den ich noch nie beim Golfspielen gesehen habe. Es beendet die Rekursion ohne if, and, oroder anderen expliziten Steuerfluss.

Basierend auf der Bedingung [s[-1]in'f-']des letzten Zeichens wird der Code entweder zurückgegeben f(s[:-1])oder nur s[:-1]unverändert. Da stres sich bei den Zeichenfolgen um die Identität handelt, können wir eine der Funktionen auswählen [str,f]und auf sie anwenden s[:-1]. Beachten Sie, dass der rekursive Aufruf mit fnicht ausgeführt wird, wenn er nicht ausgewählt ist, wodurch das häufig auftretende Problem umgangen wird, dass Python ungenutzte Optionen eifrig auswertet, was zu einer unendlichen Regression bei Rekursionen führt.

xnor
quelle
Nun, da ist mein Gehirn für den Morgen.
Don Bright
3

APL (Dyalog Unicode) , 46 Byte SBCS

Anonyme implizite Präfixfunktion.

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

Probieren Sie es online!

⎕CY'dfns'c op y die "DFNS" Bibliothek (zu erhalten hexunddec )

(... )
 das Argument
 unterscheidet sich von
'-' einem Bindestrich
(... )@ in der Teilmenge, die aus den Stellen besteht, an denen das obige Kriterium zutrifft:
dec¨ Jedes Hexadezimalzeichen in eine Dezimalzahl umwandeln
 ... @32an Position 32 (die letzte Ziffer) anwenden:
  1+ Inkrementieren
16(... )⍣≡ wiederholt anwenden mit linkes Argument 16 bis stabilen:
  = vergleichen (gibt maskieren , wo die Hexadezimalziffern 16)
  1⌽ zyklisch Drehen einen Schritt nach links (das ist das Übertragsbit)
  |+ zu , dass der Divisionsrest hinzuzufügen , wenn unterteilt (durch sechzehn, also all 16 in 0 zu machen)  wiederum Ziffern in hexadezimale Zeichendarstellungen der Länge 1 ϵ nlist (Abflachen)
1hex

Adam
quelle
3

Java 11, 152 149 111 108 Bytes

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

-38 Bytes danke an @ OlivierGrégoire .
-3 Bytes dank nur @ ASCII .

Probieren Sie es online aus.

Erläuterung:

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

Alte 149-Byte-Antwort:

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");}

Probieren Sie es online aus.

Erläuterung:

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
Kevin Cruijssen
quelle
1
111 Bytes
Olivier Grégoire
@ OlivierGrégoire Hatte nicht darüber nachgedacht, eine tatsächliche UUID zu verwenden! Schöne und kürzere Alternative. : D
Kevin Cruijssen
1
109
Nur ASCII
-1 mehr mit var statt long
ASCII
2

Python 2 , 113 112 Bytes

def f(s):a=hex(int(s.replace('-',''),16)+1+2**128);return'-'.join((a[3:11],a[11:15],a[15:19],a[19:23],a[23:-1]))

Probieren Sie es online!

Ohne Importe

TFeld
quelle
2

Retina 0.8.2 , 21 Bytes

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

Probieren Sie es online! Link enthält Testfälle. 9wird a. Erläuterung: Der reguläre Ausdruck entspricht allen nachfolgenden Zeichen fs und -s sowie einem vorangestellten Zeichen. Die Transliteration erhöht diese Zeichen dann zyklisch, als wären sie Hexadezimalziffern. Alternativer Ansatz, auch 21 Bytes:

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

Probieren Sie es online! Link enthält Testfälle. Verringert die Eingabe, um die Transliteration zu vereinfachen. Wäre also 15 Bytes, wenn es nur Kleinbuchstaben unterstützen müsste. Probieren Sie es online! Link enthält Testfälle.

Neil
quelle
2

MATLAB, 138 Bytes

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))

Ein Fehler wurde behoben, der dazu führte, dass ein Chunk nur aus Nullen bestand. Ich habe auch viel Golf gespielt, indem ich try / catch missbraucht habe. Nettoergebnis: 0 Bytes gespeichert.

Ein Versuch, mit 'cheat' zu arbeiten, ist java.util.UUIDfehlgeschlagen, da der von zurückgegebene longWert in java.util.UUID.get[Most/Least]SignificantBitseinen konvertiert wird, der zu einem doubleGenauigkeitsverlust führt. Ich lade Sie ein, einen Blick auf diesen Tisch zu werfen und lautlos "... aber warum? "

Erläuterung

Die hex2decFunktion spuckt a aus doubleund kann daher nicht die gesamte GUID auf einmal verarbeiten, um ein Überschreiten zu vermeiden flintmax. Stattdessen müssen wir den GUID-Block chunckweise mit verarbeiten split. Die Variable aprüft, ob wir eine Eins tragen müssen, und betrügerischerweise ist dies auch das anfängliche Inkrement, das wir hinzufügen. Die Bedingung für das Übertragen ist, ob die Längen der ursprünglichen und der inkrementierten Zeichenfolge nicht mehr gleich sind.

Die ursprüngliche Version war knapp 160 Byte groß, daher würde ich gerne glauben, dass dies nicht leicht zu übertreffen sein sollte.

Sanchises
quelle
2

Python 2 , 99 Bytes

s='%032x'%-~int(input().replace('-',''),16)
print'-'.join((s[:8],s[8:12],s[12:16],s[16:20],s[20:]))

Probieren Sie es online!

Keine uuid.UUIDVerwendung.

Erik der Outgolfer
quelle
2

C # (Visual C # Interactive Compiler) , 77 Byte

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

Probieren Sie es online!

-1 Byte danke an @ASCIIOnly!

Anonyme Funktion, die eine char[]als Eingabe und Ausgabe durch Ändern eines Arguments annimmt .

Die Eingabe wird von rechts nach links gescannt und nach den folgenden Regeln ersetzt.

  • Das -Zeichen wird ignoriert und die Verarbeitung fortgesetzt
  • Das FZeichen wird konvertiert 0und die Verarbeitung fortgesetzt
  • Der 9Charakter wird konvertiert Aund die Verarbeitung wird gestoppt
  • Die Zeichen A-Eund 0-8werden um 1 erhöht, und die Verarbeitung wird gestoppt
Dana
quelle
2
==70->>69
Nur ASCII
Ausgezeichnet - Danke :)
Dana
2

Powershell, 101 Bytes

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

Probieren Sie es online!

Keine externe Bibliothek oder Hex-Konvertierung. Beliebige Stringlänge. Kleinbuchstaben und Großbuchstaben sind zulässig. Die Eingabe von Zeichenfolgen, die mit übereinstimmen, ^[f-]*$ist ebenfalls zulässig.

Dieses Skript scannt von der Rückseite des Strings und erhöht jedes Zeichen um den Wert aus der Hash-Tabelle:

  • -: Inkrement = 1-1
  • 9: Inkrement = 1 + 7, Ergebnis =A
  • F: Inkrement = 1-23, Ergebnis =0
  • f: Inkrement = 1-55, Ergebnis =0
  • Inkrement = 1 für andere Zeichen

Anschließend ermittelt das Skript $p, ob das aktuelle Zeichen erhöht werden soll.

Testskript:

$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"
}

Ausgabe:

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
mazzy
quelle
1

Perl 6 , 65 Bytes

{(:16(TR/-//)+1).base(16).comb.rotor(8,4,4,4,*)».join.join('-')}

Probier es aus

Brad Gilbert b2gills
quelle
1
Das OP hat klargestellt, dass führende Nullen erhalten bleiben müssen.
Dennis
56 Bytes mit führenden Nullen
Jo King
1
Oder 53 Bytes durch mehr manuelle Bearbeitung
Jo King,
1

Gelee , 20 Bytes

-2 (und ein Bugfix) danke an Dennis!

ØhiⱮṣ0µẎḅ⁴‘ḃ⁴ịØhṁj”-

Probieren Sie es online!

Jonathan Allan
quelle
1

PowerShell , 126 Byte

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

Probieren Sie es online!

Ziemlich triviale Antwort. Ich dachte nur, ich würde die geliebte PowerShell zur Liste hinzufügen lassen :)

KGlasier
quelle
0

Perl 5, 64 Bytes

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

Die Anzahl der Klammern, die hier erforderlich sind, macht mich traurig, ->bindet aber sehr eng, da dies ->as_hexder schnellste Weg ist, eine hexadezimal formatierte Ausgabe zu erhalten.

Laufen Sie mit perl -Mbigint -p. Im Grunde konvertiert es die Zahl einfach in ein ganzes Hexadezimal, addiert eins und setzt dann die Ziffern des Ergebnisses wieder auf den ursprünglichen Wert zurück, wobei die Striche unangetastet bleiben.

Silvio Mayolo
quelle
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('-')));

ja es ist lang .. aber technisch ist es nur eine Zeile mit 1 Ausdruck? und keine schicken Bibliotheken? und es wird nicht auf eine Fuzz-Eingabe abstürzen? 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('-')));

Probieren Sie es auf Rost Spielplatz

Don Bright
quelle
0

16/32/64-Bit-x86-Assemblycode, 28 Byte

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

Rufen Sie mit ESI auf, das auf GUID zeigt. Ersetzen Sie ESI durch SI für 16-Bit oder RSI für 64-Bit (und +2 Byte).

Peter Ferrie
quelle
0

C (clang) , 62 Bytes

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

Probieren Sie es online!

AZTECCO
quelle
warten. kostet die Klein- / Großschreibung nichts ???
Nur ASCII
Ich meine, es kann sowohl Kleinbuchstaben als auch Großbuchstaben ohne Kosten für bytecount verarbeiten ?!
Nur ASCII
Ah ok .. ch-70% 32? : bis '0' ... 64 und 96 sind ein Vielfaches von 32, also 70-6 und 102-6% 32.
AZTECCO
1
Sie müssen eigentlich nicht beide behandeln, also 64
ASCII
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#))))

Probieren Sie es online!

Renzo
quelle