使用Java为字符串生成唯一ID

时间:2018-10-19 09:25:34

标签: java hashcode

我当前正在执行一项任务,该任务需要将唯一标识符附加到字符串,然后在redshift中使用该名称创建一个表。目前,我正在使用id.hashcode()生成标识符(如果不存在,我的查询就会创建表)来执行任务。但是我最近得到了1个ID,其生成的哈希码是负值,并且Redshift不允许查询中使用“-”(生成的样本名称:abc-1234)。

如何唯一标识每个传入的ID,如果该ID的表存在,则不应再次创建该表。

1 个答案:

答案 0 :(得分:0)

首先,根据定义,任何哈希码都不会比字符串本身唯一,除非您使用更多数据像时间戳一样生成它。

根据要附加到字符串的唯一标识符的类型以及需要的唯一性,您有几种可能。

1ˢᵗ)可以使用时间戳,机器IP地址和随机数,通过类似于以下方法来生成非常接近的通用唯一标识符:

public String createUniqueKey() {

    int iRnd;
    long lSeed = System.currentTimeMillis();
    Random oRnd = new Random(lSeed);
    String sHex;
    StringBuffer sUUID = new StringBuffer(32);
    byte[] localIPAddr = new byte[4];

    try {

        // 8 characters Code IP address of this machine
        localIPAddr = InetAddress.getLocalHost().getAddress();

        sUUID.append(byteToStr[((int) localIPAddr[0]) & 255]);
        sUUID.append(byteToStr[((int) localIPAddr[1]) & 255]);
        sUUID.append(byteToStr[((int) localIPAddr[2]) & 255]);
        sUUID.append(byteToStr[((int) localIPAddr[3]) & 255]);
    }
    catch (UnknownHostException e) {
        // Use localhost by default
        sUUID.append("7F000000");
    }

    // Append a seed value based on current system date
    sUUID.append(Long.toHexString(lSeed));

    // 6 characters - an incremental sequence
    sUUID.append(Integer.toHexString(iSequence.incrementAndGet()));

    iSequence.compareAndSet(16777000, 1048576);

    do {
        iRnd = oRnd.nextInt();
        if (iRnd>0) iRnd = -iRnd;
        sHex = Integer.toHexString(iRnd);
    } while (0==iRnd);

    // Finally append a random number
    sUUID.append(sHex);

    return sUUID.substring(0, 32);
} // createUniqueKey()

2ⁿᵈ):您可能希望创建随时间增加或减少的一系列键,以便对其进行排序:

private static AtomicInteger iSequence = new AtomicInteger(1048576);

/**
 * Create a universal unique key which increases over time
 * @return String of 32 characters length
 */
public String createTimeDependentKey() {
    char pad[];
    int padLen;
    StringBuilder retval = new StringBuilder(32);
    final long seed = System.currentTimeMillis();
    Random rnd = new Random(seed);
    // 10 characters time dependent part
    String timePart = String.valueOf(Long.MAX_VALUE-seed);
    padLen = timePart.length()-10;
    pad = new char[padLen];
    java.util.Arrays.fill(pad, '0');
    retval.append(pad).append(timePart);
    // 6 characters sequential
    retval.append(Integer.toHexString(iSequence.incrementAndGet()));
    iSequence.compareAndSet(16777000, 1048576);
    // 8 characters IP dependent part       
    try {
        byte[] localIPAddr = InetAddress.getLocalHost().getAddress();
        retval.append(byteToStr[((int) localIPAddr[0]) & 255]);
        retval.append(byteToStr[((int) localIPAddr[1]) & 255]);
        retval.append(byteToStr[((int) localIPAddr[2]) & 255]);
        retval.append(byteToStr[((int) localIPAddr[3]) & 255]);
    }
    catch (UnknownHostException e) {
        retval.append("7f000000");
    }
    // 8 characters random part
    String randomPart = String.valueOf(rnd.nextInt(Integer.MAX_VALUE));
    padLen = timePart.length()-8;
    retval.append(randomPart).append(generateRandomId(padLen, "0123456789abcdef", Character.LOWERCASE_LETTER));
    return retval.toString();
}

/**
 * Generate a reverse timestamp plus random int identifier of 32 characters length
 * The identifier will be composed of Long.MAX_VALUE-Current Time in Milliseconds followed by a random 32 bits integer
 * @return Numeric identifier of 32 characters length padded with zeros at the left
 */
public String generateReverseTimestampId() {
  String sTs = Str.leftPad(String.valueOf(Long.MAX_VALUE-System.currentTimeMillis()),'0',20);
  String sRd = Str.leftPad(String.valueOf(new Random().nextInt(Integer.MAX_VALUE)),'0',10);
  return Str.leftPad(sTs+sRd,'0',32);
}

3ʳᵈ)您可能想要创建仅具有给定字符集的伪唯一键:

public String generateRandomId(int iLength, String sCharset, byte byCategory ) throws StringIndexOutOfBoundsException {

  if (iLength<=0) 
    throw new StringIndexOutOfBoundsException("Uid.generateRandomId() identifier length must be greater than zero");

  if (iLength>4096) 
    throw new StringIndexOutOfBoundsException("Uid.generateRandomId() identifier length must be less than or equal to 4096");

  if (sCharset!=null) {
    if (sCharset.length()==0) throw new StringIndexOutOfBoundsException("Uid.generateRandomId() character set length must be greater than zero");
  } else {
    sCharset = "abcdefghjkmnpqrstuvwxyz23456789";
  }

if (byCategory!=Character.UNASSIGNED && byCategory!=Character.UPPERCASE_LETTER && byCategory!=Character.LOWERCASE_LETTER)
  throw new IllegalArgumentException("Uid.generateRandomId() Character category must be one of {UNASSIGNED, UPPERCASE_LETTER, LOWERCASE_LETTER}");

int iCsLen = sCharset.length();
  StringBuilder oId = new StringBuilder(iLength);
  Random oRnd = new Random();
  for (int i=0; i<iLength; i++){
    char c = sCharset.charAt(oRnd.nextInt(iCsLen));
    if (byCategory==Character.UPPERCASE_LETTER)
      c = Character.toUpperCase(c);
    else if (byCategory==Character.LOWERCASE_LETTER)
      c = Character.toLowerCase(c);
    oId.append(c);
  }
  return oId.toString();
} 

您还将需要此数组

private static String[] byteToStr = {
    "00","01","02","03","04","05","06","07","08","09","0a","0b","0c","0d","0e","0f",
    "10","11","12","13","14","15","16","17","18","19","1a","1b","1c","1d","1e","1f",
    "20","21","22","23","24","25","26","27","28","29","2a","2b","2c","2d","2e","2f",
    "30","31","32","33","34","35","36","37","38","39","3a","3b","3c","3d","3e","3f",
    "40","41","42","43","44","45","46","47","48","49","4a","4b","4c","4d","4e","4f",
    "50","51","52","53","54","55","56","57","58","59","5a","5b","5c","5d","5e","5f",
    "60","61","62","63","64","65","66","67","68","69","6a","6b","6c","6d","6e","6f",
    "70","71","72","73","74","75","76","77","78","79","7a","7b","7c","7d","7e","7f",
    "80","81","82","83","84","85","86","87","88","89","8a","8b","8c","8d","8e","8f",
    "90","91","92","93","94","95","96","97","98","99","9a","9b","9c","9d","9e","9f",
    "a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","aa","ab","ac","ad","ae","af",
    "b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","ba","bb","bc","bd","be","bf",
    "c0","c1","c2","c3","c4","c5","c6","c7","c8","c9","ca","cb","cc","cd","ce","cf",
    "d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","da","db","dc","dd","de","df",
    "e0","e1","e2","e3","e4","e5","e6","e7","e8","e9","ea","eb","ec","ed","ee","ef",
    "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9","fa","fb","fc","fd","fe","ff" };

可以找到here的完整实现。