UUID.st
changeset 2977 afc4d10019c7
parent 2954 1f5e5edc610d
child 2978 4497be5fc993
--- a/UUID.st	Fri Apr 19 11:40:35 2013 +0200
+++ b/UUID.st	Mon Apr 22 17:48:57 2013 +0200
@@ -14,7 +14,7 @@
 ByteArray variableByteSubclass:#UUID
 	instanceVariableNames:''
 	classVariableNames:'CachedMACAddress Lock SequenceNumber LastTime Increment
-		NameSpaceDNS NameSpaceDN NameSpaceURL NameSpaceOID'
+		NameSpaceToUuidBytes'
 	poolDictionaries:''
 	category:'Net-Communication-Support'
 !
@@ -67,15 +67,19 @@
     "I want to get informed about image restarts"
 
     Lock isNil ifTrue:[
-        Lock := RecursionLock new name:'UUID'.
+        Lock := RecursionLock new name:#UUID.
         LastTime := 0.
         Increment := 0.
         ObjectMemory addDependent:self.
 
-        NameSpaceDNS := self fromBytes:#[16r6B 16rA7 16rB8 16r10 16r9D 16rAD 16r11 16rD1 16r80 16rB4 16r0 16rC0 16r4F 16rD4 16r30 16rC8].
-        NameSpaceURL := self fromBytes:#[16r6B 16rA7 16rB8 16r11 16r9D 16rAD 16r11 16rD1 16r80 16rB4 16r0 16rC0 16r4F 16rD4 16r30 16rC8].
-        NameSpaceOID := self fromBytes:#[16r6B 16rA7 16rB8 16r12 16r9D 16rAD 16r11 16rD1 16r80 16rB4 16r0 16rC0 16r4F 16rD4 16r30 16rC8].
-        NameSpaceDN  := self fromBytes:#[16r6B 16rA7 16rB8 16r14 16r9D 16rAD 16r11 16rD1 16r80 16rB4 16r0 16rC0 16r4F 16rD4 16r30 16rC8].
+        NameSpaceToUuidBytes := Dictionary withKeysAndValues:#(
+                DNS  #[16r6B 16rA7 16rB8 16r10 16r9D 16rAD 16r11 16rD1 16r80 16rB4 16r0 16rC0 16r4F 16rD4 16r30 16rC8]            
+                URL  #[16r6B 16rA7 16rB8 16r11 16r9D 16rAD 16r11 16rD1 16r80 16rB4 16r0 16rC0 16r4F 16rD4 16r30 16rC8]
+                "ASN.1 OID in DER or as Text"
+                OID  #[16r6B 16rA7 16rB8 16r12 16r9D 16rAD 16r11 16rD1 16r80 16rB4 16r0 16rC0 16r4F 16rD4 16r30 16rC8]
+                "X.500 DN as DER or as Text"
+                X500 #[16r6B 16rA7 16rB8 16r14 16r9D 16rAD 16r11 16rD1 16r80 16rB4 16r0 16rC0 16r4F 16rD4 16r30 16rC8]            
+            ).
     ]
 !
 
@@ -240,6 +244,25 @@
     "
 !
 
+genUUID:nameStringOrBytes inNameSpace:namespaceString
+    "generate a namespace UUID (Version 5, hashed by SHA-1).
+     See RFC4122."
+
+    ^ (super basicNew:16) genUUID:nameStringOrBytes inNameSpace:namespaceString
+
+    "
+        self genUUID:'www.example.org' inNameSpace:'DNS'.
+        self genUUID:'http://www.exept.de' inNameSpace:'URL'.
+        self genUUID:'1.2.3.4.5' inNameSpace:'OID'.
+        self genUUID:(OSI::DERCoder encode:(OSI::ASN1_OID newID:#(1 2 3 4 5))) 
+             inNameSpace:'OID'.
+        self genUUID:'c=de, o=eXept Software AG, cn=Development' 
+             inNameSpace:'X500'.
+        self genUUID:(OSI::DERCoder encode:(OSI::DistinguishedName fromString:'c=de, o=eXept Software AG, cn=Development') asAsn1Value) 
+             inNameSpace:'X500'.
+    "
+!
+
 new
     ^ (super basicNew:16) genUUID
 
@@ -371,17 +394,11 @@
     "return the first valid MAC address (i.e. having at least one byte ~~ 0)"
 
     CachedMACAddress isNil ifTrue:[
-        |dictOfIf ipAddr|
-
         CachedMACAddress := false.      "cache the fact, that there is no MAC address" 
         [
-            dictOfIf := OperatingSystem getNetworkMACAddresses.
-
-            dictOfIf do:[:macAddress |
-                (macAddress contains:[:byte | byte ~~ 0]) ifTrue:[
-                    ^ CachedMACAddress := macAddress
-                ].
-            ].
+            CachedMACAddress := OperatingSystem getNetworkMACAddresses 
+                                    detect:[:macAddress | macAddress ~= #[0 0 0 0 0 0]]
+                                    ifNone:false.
         ] on:PrimitiveFailure do:[:ex| "ignore"].
     ].
 
@@ -656,7 +673,7 @@
     self replaceFrom:11 to:16 with:macBytes startingAt:1.
 
     "
-      self new genTimestampUUID
+      self genTimestampUUID
       self genTimestampUUID genTimestampUUID
     "
 
@@ -697,6 +714,40 @@
           Transcript showCR:(UUID genUUID).
       ].
     "
+!
+
+genUUID:nameStringOrBytes inNameSpace:namespaceString
+    "generate a namespace UUID (Version 5, hashed by SHA-1).
+     See RFC4122."
+
+    |sha1|
+
+    (self at:7) ~~ 0 ifTrue:[
+        "once created, an UUID is immutable"
+        self noModificationError.
+    ].
+
+    sha1 := SHA1Stream new.
+    sha1 
+        nextPutAll:(NameSpaceToUuidBytes at:namespaceString);
+        nextPutAll:nameStringOrBytes.
+
+    self replaceFrom:1 to:16 with:(sha1 hashValue).
+    "multiplex the 4 bit version number (Version 5 -> SHA1 Namspace UUID) in high bits of byte 7"
+    self at:7 put:(((self at:7) bitAnd:16r0F) bitOr:16r50).
+    self at:9 put:(((self at:9) bitAnd:16r3F) bitOr:16r80).
+
+    "
+        self genUUID:'www.example.org' inNameSpace:'DNS'.
+        self genUUID:'http://www.exept.de' inNameSpace:'URL'.
+        self genUUID:'1.2.3.4.5' inNameSpace:'OID'.
+        self genUUID:(OSI::DERCoder encode:(OSI::ASN1_OID newID:#(1 2 3 4 5))) 
+             inNameSpace:'OID'.
+        self genUUID:'c=de, o=eXept Software AG, cn=Development' 
+             inNameSpace:'X500'.
+        self genUUID:(OSI::DERCoder encode:(OSI::DistinguishedName fromString:'c=de, o=eXept Software AG, cn=Development') asAsn1Value) 
+             inNameSpace:'X500'.
+    "
 ! !
 
 !UUID methodsFor:'hashing'!
@@ -726,12 +777,17 @@
 displayOn:aGCOrStream
     "/ what a kludge - Dolphin and Squeak mean: printOn: a stream;
     "/ ST/X (and some old ST80's) mean: draw-yourself on a GC.
-    (aGCOrStream isStream or:[aGCOrStream == Transcript]) ifTrue:[
+
+    aGCOrStream isStream ifTrue:[
         self printOn:aGCOrStream.
         ^ self.
     ].
 
-    ^ super displayOn:aGCOrStream
+    ^ super displayOn:aGCOrStream.
+
+    "
+        self genUUID displayOn:Transcript
+    "
 !
 
 printOn:aStream
@@ -823,11 +879,11 @@
 !UUID class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/UUID.st,v 1.43 2013-03-26 17:02:21 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/UUID.st,v 1.44 2013-04-22 15:48:57 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic2/UUID.st,v 1.43 2013-03-26 17:02:21 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/UUID.st,v 1.44 2013-04-22 15:48:57 stefan Exp $'
 ! !