【问题标题】:8 chars unique String in JavaJava中8个字符的唯一字符串
【发布时间】:2011-12-09 03:22:10
【问题描述】:

有没有办法在Java中生成8个字符长的随机且唯一的String?

String id = getRandomString();

然后id 将是例如wf41Av5g

【问题讨论】:

  • 如果您想要超过 62^8 个(假设您只想要字母数字)则不行……您可能想要一个随机字符串,然后查找已生成字符串的表。
  • define "unique":每次运行该方法时都会返回不同的字符串?还是所有字符都彼此不同?还有什么?

标签: java string random


【解决方案1】:

由于以上答案都不能确保唯一性,我决定添加另一个答案。

首先我们在一个数组中定义所有有效的选项:

char[] chars = new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };

现在我们可以将算法更改为Random shuffling of an array,以获得前 8 个元素:

Random rnd = new Random();
int charsLength = chars.length;
int passLength = 8;
StringBuilder password = new StringBuilder();
for (int i = 0; i < passLength; i++)
{
    int index = rnd.nextInt(charsLength - i - 1);
    // Simple swap
    char a = chars[i + index];
    chars[i + index] = chars[i];
    chars[i] = a;
    password.append(a);
}

System.out.print(password);

它确保了唯一性,一旦char 出现在数组的前 8 个位置,它就不是下一轮的有效选择。

我得到的输出很少:

ifJjuYrR
NpY3TfIU
LGFm8Ng9
sV4Gctb7
4fyhlSuQ

【讨论】:

    【解决方案2】:

    现在你一定已经得到了答案,但是对于那些到达这个页面的人,试试这个代码:

    public class RandomValueXML {
    
        public static void main(String[] args) {
            
            System.out.println(org.apache.commons.lang3.RandomStringUtils.random(6, true, true)); 
    
        }
        
        static Set<String> getRandomUniqueStrings(int count, int length, boolean letters, boolean numbers){
            Set<String> rus = new HashSet<>();
            
            while (rus.size() < count){
                rus.add(RandomStringUtils.random(length, letters, numbers));
            }
            
            return rus;
        } 
    }
    

    这里使用set保证唯一性,使用HashSet保证读写性能更好。

    【讨论】:

    • 请注意,接受的答案是您的建议。你在上面加吗?请收下tour 并阅读How to Answer
    【解决方案3】:

    我不知道是否有一种方法可以生成 8 位唯一随机字符串,但我会创建一个离线密钥生成器服务,该服务会不断生成随机密钥并将它们插入到密钥表中,如果密钥不存在表,当您的在线应用需要密钥时,它可以从预先生成的密钥之一中获取。

    【讨论】:

    【解决方案4】:

    我知道这是一篇旧帖子,但这可能会对某人有所帮助。

    这个对我有用:

    System.out.println(UniqueIdGenerator.fromBase10(System.currentTimeMillis()));
    

    在同一个 JVM 上每毫秒应该是唯一的。

    与:

    public class UniqueIdGenerator {
    
     private static final String MIX_STRING = "abcdefghijklmnopqrstuvwxyz1234567890";
    
     private static final int MIX_STRING_LENGTH = MIX_STRING.length();
    
     public static String fromBase10(final long base10) {
        if (base10 == 0)
            return "0";
    
        long temp = base10;
        final StringBuilder sb = new StringBuilder();
    
        while (temp > 0) {
            temp = fromBase10(temp, sb);
        }
        return sb.reverse().toString();
     }
    
     private static Long fromBase10(final long base10, final StringBuilder sb) {
        final int rem = (int) (base10 % MIX_STRING_LENGTH);
        sb.append(MIX_STRING.charAt(rem));
        return base10 / MIX_STRING_LENGTH;
     }
    }
    

    您还可以更改MIX_STRING 中的字符顺序,甚至添加大写字母或符号。

    【讨论】:

      【解决方案5】:

      你可以使用RandomStringUtils

      import org.apache.commons.lang.RandomStringUtils;
      public class RandomStringUtilsTrial {
        public static void main(String[] args) {
          System.out.print("8 char string  >>>");
          System.out.println(RandomStringUtils.random(8, true, true));
      
        }
      }
      

      【讨论】:

      • 我很好奇,这如何解决 OP 的问题。我在文档中看不到任何确保唯一性的内容。
      【解决方案6】:
      long unixTime = System.currentTimeMillis() / 1000L;
      String unique_no=Long.toHexString(unixTime).toUpperCase();
      

      为您提供 HEX 格式的唯一 8 个字符的字符串。

      【讨论】:

      • 如果您每秒调用不止一次,则不是唯一的,而且绝对不是随机的!
      【解决方案7】:

      您可以根据当前时间创建此字符串。

      例如:

      2014 06 04 16 21 20 79 ---> 14 06 04 16 21 20 79

      然后,您可以使用表格(http://en.wikipedia.org/wiki/Base64 - 请注意,它们都小于 59)为字母数字字符翻译每两位(最后两位除外)

      然后你会收到

      14 - O
      06 - G
      04 - 电子
      16 - 问
      21 - V
      20-U

      OGEQVU79

      【讨论】:

      • 这并不能保证唯一性 - 考虑并发线程甚至单个线程快速连续重复执行此操作
      【解决方案8】:

      如果唯一性很重要,则不能简单地随机生成字符串。没有办法避免碰撞。即使是 UUID 也可能发生冲突,尽管这种可能性很小。

      你可以对你使用过的字符串做一个记录,当你生成一个新的随机字符串时,检查记录看是否重复,如果重复,丢弃再试一次。

      但是,我建议您不要生成随机数。相反,保留一个计数器,并对其输出进行加密以生成看起来随机的数字。如果您正确执行此操作,则可以保证它们永远不会发生碰撞。见an earlier answer of mine,或one by Rossum

      【讨论】:

        【解决方案9】:

        请尝试以下代码:

        private String uniqid() {
            Random random = new Random();
            String tag = Long.toString(Math.abs(random.nextLong()), 36);
            return tag.substring(0, 8);
        }
        

        【讨论】:

        • 我相信这并没有完全做正确的事,因为 Long.toString 丢弃了前导零。但是,您可以将代码扩展到零填充短字符串,而不是修剪它们。
        【解决方案10】:

        使用java.util.UUID 的快速而肮脏的解决方案:

        public String getRandomString(int length) {
            return UUID.randomUUID().toString().subSequence(0, length);
        }
        

        【讨论】:

        • 我生成了两次 ff808181328864ba01328864bc590000 和 ff808181328864ba02328864bc5902300。如果我只取 8 个第一个字符,我将得到相同的字符串 :(
        【解决方案11】:
        public String getRandomString(int length, char[] characterSet) {
            StringBuilder sb = new StringBuilder();
        
            for (int loop = 0; loop < length; loop++) {
                int index = new Random().nextInt(characterSet.length);
                sb.append(characterSet[index]);
            }
        
            String nonce = sb.toString();
            return nonce;
        }
        

        【讨论】:

          【解决方案12】:

          uniqueness 属性取决于您使用它的范围。 Java 当然可以生成随机字符串,但如果您想要一个通用唯一 标识符,您可以使用UUID 类。

          String unique = UUID.randomUUID().toString();
          

          【讨论】:

          • 这很好,但我只需要 8 个字符,否则我会毫无疑问地使用它。
          • UUID 是结构化的;它们的字段以特定方式生成,并非每一位都同样独特。这意味着您不能只是从它们中切出随机位并期望它们保持独特。请参阅 Danny 对 Oliver's answer 的评论,了解此问题的实际效果。
          • @danny, i.e., String eightChars = unique.substring(28);
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-04
          • 2017-04-15
          • 2011-08-14
          • 2021-10-10
          • 2020-07-31
          • 1970-01-01
          相关资源
          最近更新 更多