package er.extensions.foundation;
import java.security.SecureRandom;
import com.webobjects.foundation.NSData;
/**
* Helper functions for UUID
*
*/
public class UUIDUtilities {
private static final String validHexCharacters = "ABCDEF0123456789abcdef";
static final SecureRandom randomGenerator = new SecureRandom();
public final static int typeByteOffset = 6;
public final static int variationByteOffset = 8;
/**
* Generate a type 4 UUID from a secure random source like the java UUID class.
* @return a new UUID in a NSData
*/
public static NSData generateAsNSData() {
return new NSData(generateAsByteArray());
}
/**
* Generate a type 4 UUID from a secure random source like the java UUID class.
* @return a new UUID in a byte[]
*/
private static byte[] generateAsByteArray() {
byte[] value = new byte[16];
randomGenerator.nextBytes(value);
value[typeByteOffset] &= 0xF; // Clear the type part of the byte
value[typeByteOffset] |= 0x40; // Set the type part of the byte to random
value[variationByteOffset] &= 0x3F; // Clear the variant part of the byte
value[variationByteOffset] |= 0x80; // set to IETF variant
return value;
}
/**
* Decode a string representing a UUID in hex.
* All non hex char are filtered before the decoding, any formats are accepted.
* @param uuid the string representing a UUID
* @return the decoded UUID in a NSData
*/
static public NSData decodeStringAsNSData(String uuid) {
return new NSData(decodeStringAsByteArray(uuid));
}
/**
* Decode a string representing a UUID in hex.
* All non hex char are filtered before the decoding, any formats are accepted.
* @param uuid the string representing a UUID
* @return the decoded UUID in a byte[]
*/
static public byte[] decodeStringAsByteArray(String uuid) {
if (uuid == null) {
throw new IllegalArgumentException("Null is not a valid UUID value.");
}
String cleannedUuid = ERXStringUtilities.removeExceptCharacters(uuid, validHexCharacters);
if (cleannedUuid.length() != 32) {
throw new IllegalArgumentException("\""+uuid+"\" is not a valid hex string representing a byte[16].");
}
try {
return ERXStringUtilities.hexStringToByteArray(cleannedUuid);
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException("\""+uuid+"\" is not a valid hex string representing a byte[16].", e);
}
}
/**
* Encode a UUID in a String using the usual format 12345678-1234-1234-1234-123456789ABC
* @param uuid a NSData containing a UUID
* @return the encoded UUID
*/
static public String encodeAsPrettyString(NSData uuid) {
return encodeAsPrettyString(uuid.bytes());
}
/**
* Encode a UUID in a String using the usual format 12345678-1234-1234-1234-123456789ABC
* @param uuid a byte[] containing a UUID
* @return the encoded UUID
*/
static public String encodeAsPrettyString(byte[] uuid) {
String rawString = encodeAsString(uuid);
StringBuilder formattedString = new StringBuilder();
formattedString.append(rawString.substring(0, 8));
formattedString.append("-");
formattedString.append(rawString.substring(8, 12));
formattedString.append("-");
formattedString.append(rawString.substring(12, 16));
formattedString.append("-");
formattedString.append(rawString.substring(16, 20));
formattedString.append("-");
formattedString.append(rawString.substring(20, 32));
return formattedString.toString();
}
/**
* Encode a UUID in a String in hex
* @param uuid a NSData containing a UUID
* @return the encoded UUID
*/
static public String encodeAsString(NSData uuid) {
return encodeAsString(uuid.bytes());
}
/**
* Encode a UUID in a String in hex
* @param uuid a byte[] containing a UUID
* @return the encoded UUID
*/
static public String encodeAsString(byte[] uuid) {
if (uuid == null) {
throw new IllegalArgumentException("Null is not a valid UUID value.");
}
String rawString = ERXStringUtilities.byteArrayToHexString(uuid);
if (uuid.length != 16) {
throw new IllegalArgumentException("\""+rawString+"\" is not a byte[16].");
}
return rawString;
}
}