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

io.continual.util.data.UniqueStringGenerator Maven / Gradle / Ivy

There is a newer version: 0.3.14
Show newest version
/*
 *	Copyright 2019, Continual.io
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *	
 *	http://www.apache.org/licenses/LICENSE-2.0
 *	
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */

package io.continual.util.data;

import java.nio.ByteBuffer;
import java.util.UUID;

import com.github.f4b6a3.ulid.Ulid;

/**
 * create a string that's unlikely to be guessed
 */
public class UniqueStringGenerator
{
	/**
	 * Create a ULID id. See https://github.com/ulid/spec.
	 * @return a ULID rendered as a string
	 */
	public static String createUlid ()
	{
		return Ulid.fast().toString();
	}
	
	/**
	 * Create a unique string.
	 * @param nonsense extra text or null
	 * @return a unique string
	 */
	public static String create ( String nonsense )
	{
		final byte[] val = createValue ( nonsense );
		return TypeConvertor.bytesToHexString ( val );
	}

	/**
	 * Create a key string using the given alphabet of characters. This is meant
	 * to help create license-key style strings, where the alphabet is restricted
	 * to all upper case Latin letter and numbers, for example.
	 * 
	 * @param nonsense text added to the "seed" for value generation
	 * @param alphabet the set of characters allowed in the output string
	 * @return a likely unique string using the given alphabet.
	 */
	public static String createKeyUsingAlphabet ( String nonsense, String alphabet )
	{
		final int alphabetLength = alphabet.length ();
		final byte[] bytes = createValue ( nonsense );
		final StringBuffer sb = new StringBuffer ();
		for ( byte b : bytes )
		{
			final int letterIndex = Math.abs ( b ) % alphabetLength;
			final char letter = alphabet.charAt ( letterIndex );
			sb.append ( letter );
		}
		return sb.toString ();
	}

	/**
	 * Create a key string using the given alphabet of characters, with the requested length.
	 * @param nonsense text added to the "seed" for value generation
	 * @param alphabet the set of characters allowed in the output string
	 * @param length the length of the output string
	 * @return a likely unique string of the given length using the given alphabet.
	 */
	public static String createKeyUsingAlphabet ( String nonsense, String alphabet, int length )
	{
		String result = createKeyUsingAlphabet ( nonsense, alphabet );
		while ( result.length () < length )
		{
			result += createKeyUsingAlphabet ( nonsense, alphabet );
		}
		return result.substring ( 0, length );
	}

	/**
	 * Create a URL compatible unique key
	 * @param nonsense text added to the "seed" for value generation
	 * @return a likely unique string that works easily in URLs
	 */
	public static String createUrlKey ( String nonsense )
	{
		return createKeyUsingAlphabet ( nonsense, kUrlKeyAlphabet );
	}

	/**
	 * Create a key string that uses a Microsoft style license key alphabet. 
	 * @param nonsense text added to the "seed" for value generation
	 * @return a Microsoft style license key string
	 */
	public static String createMsStyleKeyString ( String nonsense )
	{
		final String original = createKeyUsingAlphabet ( nonsense, kLicenseKeyAlphabet );

		final StringBuffer sb = new StringBuffer ();
		int position = -1;
		for ( int i=0; i 0 && position % 5 == 0 )
			{
				sb.append ( " " );
			}
			sb.append ( letter );
		}
		return sb.toString ();
	}

	/**
	 * Return a base64 encoded UUID
	 * @return a base64 encoded UUID string
	 */
	public static String createEncodedUuid ()
	{
		// create a uuid
		final UUID uuid = UUID.randomUUID ();

		final ByteBuffer bb = ByteBuffer.wrap ( new byte [16] );
		bb.putLong ( uuid.getMostSignificantBits () );
		bb.putLong ( uuid.getLeastSignificantBits () );
	    final byte[] uuidArray = bb.array();

		String encoded = TypeConvertor.base64Encode ( uuidArray );
		if ( encoded.endsWith ( "==" ) )
		{
			encoded = encoded.substring ( 0, encoded.length () - 2 );
		}
		else if ( encoded.endsWith ( "=" ) )
		{
			encoded = encoded.substring ( 0, encoded.length () - 1 );
		}

		return encoded;
	}
	
	private static final String kLicenseKeyAlphabet = "123456789BCDFGHJKLMNPQRTVWXYZ";
	private static final String kUrlKeyAlphabet = "0123456789ABCDFGHJKLMNPQRTVWXYZabcdefhigjklmnopqrstuvwxyz";

	private UniqueStringGenerator()
	{
	}

	private static byte[] createValue ( String nonsense )
	{
		final StringBuffer sb = new StringBuffer ();
		sb.append ( UUID.randomUUID ().toString () );
		if ( nonsense != null )
		{
			sb.append ( nonsense );
		}
		sb.append ( System.currentTimeMillis () );

		return OneWayHasher.pbkdf2Hash ( UUID.randomUUID ().toString (), sb.toString() );
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy