All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.internal.util.UUID Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * ___________________
 *
 *  Copyright 2006-2007 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.adobe.internal.util;

import java.math.BigInteger;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.util.Random;


/**
 * This class implements a version 4 (random) UUID, conforming to
 * RFC4122.
 */
public final class UUID 
{
	/**
	 * Create a fake address once and then reuse it.
	 */
	private static String mFakeMACAddress = null;

	/**
	 * Random number generator to use.
	 */
	private static Random mSeeder = null;

	static {
		// Try to get this specific one that's FIPS compliant, otherwise
		// fall back on the default
		try {
			mSeeder = SecureRandom.getInstance("FIPS186PRNG", "JsafeJCE");
		} catch (NoSuchAlgorithmException e) {
			mSeeder = new SecureRandom();
		} catch (NoSuchProviderException e) {
			mSeeder = new SecureRandom();
		}
	}

	/**
	 * Private default constructor for utility class.
	 */
	private UUID() 
	{
	}

	/**
	 * This function creates a version 4 (random) UUID, conforming to
	 * RFC4122, like "uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6".
	 *
	 * @return a string containing the hex-encoded UUID.
	 */
	public static String createUUID() 
	{
		if (mFakeMACAddress == null) 
		{
			byte[] macBytes = new byte[6];
			mSeeder.nextBytes(macBytes);

			BigInteger bi = new BigInteger(1, macBytes);
			String macStr = bi.toString(16);
			mFakeMACAddress = padHex(macStr, 12) + macStr;
		}

		byte[] timeLow = new byte[4];
		byte[] timeMid = new byte[2];
		byte[] timeHighAndVersion = new byte[2];
		byte[] clockSeqHiAndReserved = new byte[1];
		byte[] clockSeqLow = new byte[1];
		mSeeder.nextBytes(timeLow);
		mSeeder.nextBytes(timeMid);
		mSeeder.nextBytes(timeHighAndVersion);
		mSeeder.nextBytes(clockSeqHiAndReserved);
		mSeeder.nextBytes(clockSeqLow);

		// Set the two most significant bits of the
		// clock_seq_hi_and_reserved to zero and one, respectively
		clockSeqHiAndReserved[0] &= 0x3f;
		clockSeqHiAndReserved[0] |= 80;

		// Set the four most significant bits of the time_hi_and_version
		// field to the 4-bit version number (in this case 4)
		timeHighAndVersion[0] &= 0x0f;
		timeHighAndVersion[0] |= 40;

		StringBuilder uuid = new StringBuilder("uuid:").
		append(hexFormat(getInt(timeLow), 8)).
		append('-').
		append(hexFormat(getInt(timeMid), 4)).
		append('-').
		append(hexFormat(getInt(timeHighAndVersion), 4)).
		append('-').
		append(hexFormat(getInt(clockSeqHiAndReserved), 2)).
		append(hexFormat(getInt(clockSeqLow), 2)).
		append('-').
		append(mFakeMACAddress);

		return uuid.toString();
	}

	/**
	 * Convert a byte array to an integer.  The 0th byte in the array is the most significant.  For example,
	 * [1, 2] becomes (1 << 8) + 2, or 258.
	 * @param bytes the byte array to convert
	 * @return an integer
	 */
	private static int getInt(final byte[] bytes) 
	{
		int i = 0;
		int j = 8 * (bytes.length - 1);

		for (int k = 0; j >= 0; k++) 
		{
			int l = bytes[k] & 0xff;
			i += (l << j);
			j -= 8;
		}
		return i;
	}

	/**
	 * Convert an integer to hexadecimal, padded with leading zeros.
	 * @param i the integer to convert
	 * @param j the number of digits to return
	 * @return the converted string
	 */
	private static String hexFormat(final int i, final int j) 
	{
		String s = Integer.toHexString(i);
		return padHex(s, j) + s;
	}

	/**
	 * Return a string of zeros long enough to pad a string to the desired length.
	 * @param s the string to pad
	 * @param i the number of digits the result should have
	 * @return the necessary string of zeros
	 */
	private static String padHex(final String s, final int i) 
	{
		StringBuilder tmpBuffer = new StringBuilder();

		if (s.length() < i) 
		{
			for (int j = 0; j < (i - s.length()); j++) 
			{
				tmpBuffer.append('0');
			}
		}
		return tmpBuffer.toString();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy