聊胜于无 Java之唯一无序数生成

java版本生成唯一编号的程序 java版的生成唯一编号的一个小程序 立即下载

聊胜于无
Java之唯一无序数生成

Wayne Huang

2011年10月

1  背景介绍

在许多项目中ID号是一个永恒的主题。在绝大多数情况下,这个唯一ID产生相对比较容易,毕竟现在众多的项目都是基于数据库的,只要把数据库的主键拿出来作为ID就可以确保ID在整个系统中的唯一性了。但也存在一些特殊情况。比如,一个在线订单生成。考虑到订单的特殊性,有时候会被要求订单号要没有规律不连续。但是我们也知道订单号是必须具有唯一性的。然而,一般数据库的主键都是采用自增数作为主键的。因此,这里如果再用主键作为订单号就会存在问题。当然,除了这个情况外,还有许多其他情况。诸如,需要自动的生成一个随机的用户ID等。
考虑到以上的背景,我这篇将继上一篇《聊胜于无 Java之Caesar与Vigenere实现》做一个唯一的伪随机数生成。作为对上一篇看上去挺简陋甚至不怎么安全的加密算法做一个具有现实意义的应用实现。话说,这两个坑爹的算法,如果加以合理的组合运用还是挺有用处的。其实大多数的安全问题,都是因为人为因素造成的和算法本身问题没太大的关系。

2  实现分析

众所周知,在计算机中,用算法实现的真实随机数是不可能存在的。当然,如果要从哲学角度考虑的话,那就是偶然和必然的问题了。就拿抛硬币来说,你可以把抛掷的结果看成是随机的,但是根据力学分析去分析每一个抛掷过程,你发现抛硬币的结果又不是随机的。

2.1  前期分析

扯那么多废话,再回到我们的主题上。如果要生成唯一随机ID,众所周知的办法是用GUID来实现。但是,如果你了解GUID的生成,就会知道GUID的生成只是将发生相同GUID的几率降到一定数值之下而已,并不能百分百保证不重复,虽然这个重复的概率比中彩票都低。而且,诸如用户ID这种情况,要用户每次登陆都输入那么长一串GUID显然是不现实的。
那么,我们来看看第二种严格符合题意的做法。现在,我们被要求的有两点:第一是随机的一个数,第二是唯一的。那么,生成一个随机数还是比较简单的,那就用Random做就OK了。接下来要满足唯一性,那也不难,把每次生成结果保存起来,之后每生成一个随机ID,就到历史里去查一下有没有重复,如果有重复就重新生成一个,周而复始直到满足唯一性。乍看之下这个算法真是"天衣无缝"啊~,话说很多人都一开始会觉得这个算法的确不错。但是,仔细想想却存在问题。如果是几个这样的ID问题不是很大,但如果要生成数量众多的ID呢?"理想情况"下,每个ID都要到历史里去遍历一遍所有的ID。但是,对于限定ID位数的情况下,随着已生成ID的数量增加,发生冲突的几率也会提高。这样的话,将直接导致算法不可用。

2.2  实现思路

根据上面的分析,是不是觉得实现这样一个"小问题",还需要很多的精力去思考呢?很多时候,我们看似简单的问题,真正实现起来却会遇到很多问题。如果作为一个普通的coder,那问题不是很严重。但是,如果作为一个leader,不能正确的预见到所要面临的问题,那就没有成为leader的资格。
那我们现在透过现象看本质。我们现在最容易拿到具有唯一性的数据是什么?是数据的ID,但这是一个有序数列。那么我们接下来要做什么?就是让这个有序数列看不出有序,让人产生迷惑感。那什么能让人对"有意义"的东西产生迷惑呢?对,就是加密算法。加密算法的本质就是将一组有意义的数据通过处理变成无意义的。这样看来,算法的思路就很简单了。就是把ID经过某个加密算法处理后即可。

3  算法实现

根据刚才的想法,那么我们首先想到的应该是MD5这类算法,但是那个生成的签名是固定的128bit数据,转换成可输入的字符,有32个字符。这样的话,用GUID效果或许会更好。那么,其次我们应该想到的是AES算法,他的雪崩效应令人映像深刻。但是AES每个加密块都是固定长度,而且加密之后还要字符串化,最主要的是AES加密算法实现也比较复杂。所以,综合以上考虑,是否突然发现或许可以用Caesar实现呢?

3.1  算法代码

那么,根据思路,我们实现了如下的代码。
import java.util.Random;

public class RandomId {
    private Random random;
    private String table;
    public RandomId() {
        random = new Random();
        table = "0123456789";
    }
    public String randomId(int id) {
        String ret = null,
            num = String.format("%05d", id);
        int key = random.nextInt(10), 
            seed = random.nextInt(100);
        Caesar caesar = new Caesar(table, seed);
        num = caesar.encode(key, num);
        ret = num 
            + String.format("%01d", key) 
            + String.format("%02d", seed);
        
        return ret;
    }
    public static void main(String[] args) {
        RandomId r = new RandomId();
        for (int i = 0; i < 30; i += 1) {
            System.out.println(r.randomId(i));
        }
    }
}

这段代码是基于上一篇《聊胜于无 Java之Caesar与Vigenere实现》的代码实现的。接受一个有序的ID数字序列,输出一个至少8位的唯一随机的字符串。

3.2  代码分析

通过执行代码,我们得到一组随机的由数字组成的ID字符串。由于生成的原理,所以不会因为生成ID的数量增加而造成算法性能下降。接下来我们看看,这个随机的序列真是唯一的么?从算法可知,根据这个随机序列,我们能够还原出原来的唯一ID。这也就证明,这个随机的序列是唯一。并且,在第三方不知道key和seed的长度与位置的情况下,以及算法实现的情况下,是很难还原出原本有序的ID的。而且,由于这类ID一般会保存在数据库中,同时一个有序ID能够对应多个无序的ID,所以,即使知道整个生成的细节,也很难根据有序ID伪造出一个合法的无序ID。

4  总结

看过上一篇Caesar与Vigenere实现的人,一定会觉得那样"古老"的手工密码,貌似没有什么实际可用的意义。但是,通过这篇文章的补充,或许会给你的思路一些拓展。我也希望你能有更多的想法和我们分享。我想,很多看似"无用"的东西,经过合理的运用,就会在不同的时代发挥其不同的作用。
JAVA自带的方法生成唯一ID java中有自带的方法可以自动帮助我们实现id的获取,可以作为稳定的工具类。可自定义。 立即下载

相关推荐

生成全局唯一编号

订单系统生成全局唯一的编号,编号是纯数字的。

java生成唯一数

在Java中生成唯一数可以使用以下几种方法: UUID (Universally Unique Identifier) 类: UUID 类生成的是一个 128 位的数字,其中包含了一个 60 位的时间戳,代表当前的时间。UUID 类的静态方法 randomUUID() 可以生成一个唯一的 UUID。 在数据库中使用自增字段: 大多数数据库都支持自增字段,这意味着每次插入一条新的记录时,自增字段...

weixin_35750747的博客 3157

java根据时间生成唯一ID

java根据时间生成唯一ID,普通的根据时间生成的ID放在循环内很容易重复。

无序唯一ID生成算法

最近遇到一个需要生成无序唯一ID的问题,虽然只是个小问题,也花了一些时间思考,因此记录一下。以下介绍几种方法。 一、直接生成随机数 1. GUID 这个方法应该最容易想到,GUID就是一个利用随机算法生成的128bit的随机数,并不保证前后生成的两个数字不相同,但由于长度足够长,所以生成的两个数字重复的概率非常小,可以认为是不会重复的。 然而这么长的数字并不适合用作会议号,所以该方案不合适。 2.随机数+查重 这个方法也很容易想到: 1 生成随机数 2 查询数据库,生成的随机数是否已被使用 2-1

cocoti的博客 2409

Hi3516CV610开发板实战:从零搭建智能视觉监控系统

本文详细介绍了从零开始基于Hi3516CV610开发板搭建智能视觉监控系统的完整实战流程。涵盖硬件连接、系统配置、摄像头集成、网络设置、固件烧录到视频处理与智能分析功能开发,提供了丰富的实践经验和调试技巧,帮助开发者快速掌握嵌入式视觉系统开发。

vvv99的博客 561

智能车学习日记【二】————十字和斜入十字

智能车学习日记【二】————十字和斜入十字 文章目录 智能车学习日记【二】————十字和斜入十字 前言 一、普通十字补线 二、斜入十字 1.判断是否为斜入十字和斜入十字类型 2.找斜入十字拐点 总结 前言 经过了一个多月的学习,小白的我终于也是能较稳定调出了2.8m以上的四轮车,过程中也遇到了很多困难,其中就有十字补线和斜入十字补线。尤其是斜入十字也是困扰了我快一周,现在和大家分享一下我处理斜入十字的方法(我的方法其实还有很多漏洞需要改进,仅供大家参考理解一下,欢迎各位在评论区指点出可

bsefef的博客 2740

Java中唯一数的生成

唯一数的生成很简单,基本上以时间为基础进行生成。在JDK里面已经有java.util.UUID类可以生成唯一的随机数。如果希望生成的唯一数为特定的格式,那么就需要自己来生成唯一数了。生成唯一数时有两个因素是必须在考虑的: 必须保证唯一,这个一般以时间为基础进行变化。高效,当然越高效越好。 有时我们希望在生成的唯一数中包含特定的内容,如把当前时间,如20110609132641,作为前缀

CHBSRZF的博客 2563

Unsloth Desktop 本地大模型微调量化实战指南

大语言模型的本地化定制正在成为开发者与内容创作者的重要需求,而微调与量化则是其中最关键的两项技术。LoRA 与 QLoRA 通过仅训练少量低秩矩阵,大幅降低显存占用和训练成本,让消费级 GPU 也能完成模型适配;GGUF 格式则打通了训练与推理的边界,使微调后的模型可直接接入 Ollama、llama.cpp 等主流推理引擎。本文以 Unsloth Desktop 为切入对象,从其底层加速原理出发,梳理了环境准备、模型加载、对话测试、量化导出、微调验证及 API 批量调用的完整链路,并针对显存优化、端口冲突

weixin_29055137的博客 397

java生成唯一数字

用UUID类生成唯一标识的时候,会生成一个十六进制的整数,但是不能作为数据库long型字段的唯一标识,用下面的办法可以实现数据库long型标识的生成:public class ProfileUtil { private static AtomicInteger counter = new AtomicInteger(0); /** * 长生消息id ...

weixin_33860722的博客 1341

六自由度机械臂运动学分析及其轨迹规划

六自由度机械臂轨迹规划 通过对比三次多项式插值法与五次多项式插值法的效果,选取后者对机械臂进行轨迹规划,将运动学解导入Matlab Robotics Toolbox仿真,得到各关节角度、速度和加速度与时间关系曲线。 三次多项式插值法 三次多项式有4个待定系数,可同时对起始点和目标点的角度和角速度给出约束条件。 数学公式 MATLAB代码 五次多项式插值法 五次多项式有6个待定系数,可同时对起始点和...

两条眉毛 6万+

使用STM32微控制器实现光电传感器的接口和数据处理

本文将介绍如何使用STM32微控制器实现光电传感器的接口和数据处理的方案,包括硬件设计、引脚配置、数据采集、滤波和阈值判断等关键步骤,并给出相应的代码示例。本文将介绍如何使用STM32微控制器实现光电传感器的接口和数据处理的方案,包括硬件设计、引脚配置、数据采集、滤波和阈值判断等关键步骤,并给出相应的代码示例。在光电传感器的接口和数据处理的实现过程中,要关注系统的性能。在使用STM32微控制器实现光电传感器的接口和数据处理之前,需要设计一个合适的硬件平台。

weixin_66608063的博客 3200

java唯一无序id生成

1、背景介绍   在许多项目中ID号是一个永恒的主题。在绝大多数情况下,这个唯一ID产生相对比较容易,毕竟现在众多的项目都是基于数据库的,只要把数据库的主键拿出来作为ID就可以确保ID在整个系统中的唯一性了。但也存在一些特殊情况。比如,一个在线订单生成。考虑到订单的特殊性,有时候会被要求订单号要没有规律不连续。但是我们也知道订单号是必须具有唯一性的。然而,一般数据库的主键都是采用自增数作为主

xiaomojun的专栏 1万+

OpenClaw 2026.3.13 踩坑实录:飞书HTTP协议降级Bug与多版本回归问题汇总

摘要:OpenClaw v2026.3.13存在多个严重回归问题,包括飞书API调用协议意外降级为HTTP导致连接失败(#46100)、本地Gateway诊断矛盾(#45504)及设备配对CLI命令失效等。该版本发布流程本身也存在异常,被迫以v2026.3.13-1标签重新发布。建议飞书用户回退至v2026.3.8稳定版,其他用户谨慎升级。本文详细记录了各Bug现象、影响范围及临时解决方案,并梳理了飞书通道的"多版本回归史",指出其根源在于架构变迁和测试覆盖不足。最后提供了包含配置备份、

Maynor的博客 869

Java生成四位纯数字并且确保唯一性

定义出实体类pojo,mapper,service这部分代码就不写了,我用的mybatisPlus,但是只要是能和数据库交互能够insert数据就行。

qq_42807952的博客 1191

Google 二次签名 导致 Facebook , Google 登录失败

google 授权登录

xq610928的博客 1957

手把手带你实现DAF-Net:零代码基础入门红外与可见光图像融合(从理论到实战)

本文介绍了红外与可见光图像融合技术及DAF-Net网络的应用。红外图像能捕捉热源但缺乏细节,可见光图像纹理丰富但在低光环境下表现不佳。DAF-Net采用双分支特征提取和动态注意力融合架构,能智能分配特征权重实现优势互补。文章详细讲解了环境配置、数据集准备(如TNO数据集)和预处理方法,并提供了DAF-Net的核心代码实现,包括特征提取、注意力融合和图像重建模块。通过该技术可在安防、自动驾驶等领域获得更优质的融合图像,提升视觉感知能力。

m0_71589036的博客 228

java 获得唯一 数字_java生成唯一数字

java生成唯一数字用UUID类生成唯一标识的时候,会生成一个十六进制的整数,但是不能作为数据库long型字段的唯一标识,用下面的办法可以实现数据库long型标识的生成:public class ProfileUtil {private static AtomicInteger counter = new AtomicInteger(0);/*** 长生消息id*/public static lo...

weixin_36221149的博客 3159

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Java中生成一个唯一值的方式

现总结几种生成一个唯一值的方式 第一种:采用nanoTime() 第二种:采用UUID类 第三种:采用数据指纹

Tryking的博客 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

java 生成 唯一随机字符串

生成唯一随机字符串在Java中的应用 在Java开发中,有时候我们需要生成一个唯一的随机字符串,用于标识某个实体或者作为密钥。本文将介绍如何在Java中生成唯一的随机字符串,并提供代码示例。 为什么需要生成唯一的随机字符串? 生成唯一的随机字符串可以避免重复和碰撞,确保标识的唯一性。在一些场景下,比如生成密码、生成订单号、...

weixin_40356809的博客 543

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Java 生成最大16位唯一数字ID,百万并发不重复

在开发过程中,集成了mybatis-plus,数据库在设计过程中,ID逐渐并没有使用自增的方式来生成逐渐,而是采用了它默认的ID生成规则,由于考虑到ID索引查询到问题,因此ID字段设置为数字类型,考虑到业务可能出现的增长,因此ID设置为bigint类型,而Java对应的属性为Long类型。 但是在实际使用中发现,默认生成的ID基本都是20位长度,由于前端js 最多只能识别16位ID,超过16位ID就会失去精度,起初考虑全局过滤,在返回给前端时将ID转换成string,但是觉得...

weixin_45922571的博客 7662

聊胜于无 Java之Caesar与Vigenere实现

聊胜于无 Java之Caesar与Vigenere实现 Wayne Huang 2011年10月 1背景介绍 话说目前做所谓"企业"开发的语言基本就集中在运用.Net和J2EE上了。又话说,在下很不幸又和Java"同流合污"了一把。现在回想起来,真是感慨万千啊~遥想公瑾当年,小乔初嫁了,雄姿英发,羽扇纶巾,谈笑间,强虏灰飞烟灭。~ 额,下面插播一下正...

weixin_30563917的博客 165

Java中生成唯一ID的方法

有时我们不依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,这时就需要用程序来生成一个唯一的全局ID。 UUID 从Java 5开始, UUID 类提供了一种生成唯一ID的简单方法。UUID是通用唯一识别码 (Universally Unique Identifier)的缩写,UUID来源于OSF(Open Software Foundation,开源软件基金会)的D...

王浩的技术博客 2万+

用java生成永远唯一的id

一,什么是UUIDUUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。目前...

yuanopen 4万+

Java生成唯一的long型数字id

最近用的java中用到了唯一的数字id。网上查了有几种主流方式,如hashcode,nanotime等,但是这几种都有可能出现重复。所以博采众长,自己写了一个生成19位long型唯一数字id 的工具类,大家一起探讨一下,代码是否可行,欢迎留言。 其实思路很简单: 1.获取nanoTime + 随机数,但是由于nanaTime前几位是相同的,所以前几位用...

code_guo的博客 1万+
上一篇: 聊胜于无 Java之Caesar与Vigenere实现
下一篇: J2EE表单验证的前后台统一实现
VisionCat
博客等级 码龄24年 459粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值