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