浅谈Java生成唯一标识码的三种方式

以下是详细讲解“浅谈Java生成唯一标识码的三种方式”的完整攻略。

浅谈Java生成唯一标识码的三种方式

在实际开发中,常常需要生成唯一标识码。Java提供了多种方式来生成唯一标识码,下面将介绍其中三种方式。

1. UUID

UUID(Universally Unique Identifier)是一种由网络软件工程师在分布式计算环境中,为了在此环境下生成唯一的标识符,而设计的一种机制。

Java中有一个UUID类,可以用来生成UUID标识符。示例代码如下:

import java.util.UUID;

public class UUIDGenerator {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println(uuid.toString());
    }
}

运行上面的代码,输出结果如下:

c525c8d2-a9af-45a0-91ab-d1f1d7ed8c3f

2. Snowflake算法

Snowflake算法是Twitter开源的分布式ID生成算法。它生成的ID有时间序列,可以根据时间排序。生成的ID是一个long类型的整数,可以方便地存储在数据库中。Snowflake算法的实现思路如下:

首先,将时间戳、数据中心标识和机器标识合并成一个64位的整数。

然后,将64位的整数分成五个部分:

  1. 1位:符号位,始终为0。
  2. 41位:时间戳,精确到毫秒级,可以使用69年。
  3. 5位:数据中心标识,最多支持32个数据中心。
  4. 5位:机器标识,最多支持32台机器。
  5. 12位:序列号,每毫秒最多支持4096个序列号。

示例代码如下:

public class SnowflakeGenerator {
    private static final int datacenterIdBits = 5;
    private static final int machineIdBits = 5;
    private static final int sequenceBits = 12;

    private static final long maxDatacenterId = ~(-1L << datacenterIdBits);
    private static final long maxMachineId = ~(-1L << machineIdBits);
    private static final long maxSequence = ~(-1L << sequenceBits);

    private static final long machineIdShift = sequenceBits;
    private static final long datacenterIdShift = sequenceBits + machineIdBits;
    private static final long timestampShift = sequenceBits + machineIdBits + datacenterIdBits;

    private static final long twepoch = 1629319086895L; // 2021-08-19 17:58:06
    private static long datacenterId = 1L;
    private static long machineId = 1L;
    private static long sequence = 0L;
    private static long lastTimestamp = -1L;

    public static void setDatacenterId(long datacenterId) {
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException("datacenterId can't be greater than " + maxDatacenterId + " or less than 0");
        }
        SnowflakeGenerator.datacenterId = datacenterId;
    }

    public static void setMachineId(long machineId) {
        if (machineId > maxMachineId || machineId < 0) {
            throw new IllegalArgumentException("machineId can't be greater than " + maxMachineId + " or less than 0");
        }
        SnowflakeGenerator.machineId = machineId;
    }

    public static synchronized long nextId() {
        long timestamp = timeGen();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        }

        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & maxSequence;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }

        lastTimestamp = timestamp;

        return ((timestamp - twepoch) << timestampShift) |
                (datacenterId << datacenterIdShift) |
                (machineId << machineIdShift) |
                sequence;
    }

    private static long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    private static long timeGen() {
        return System.currentTimeMillis();
    }
}

使用Snowflake算法生成ID的示例代码如下:

public class SnowflakeDemo {
    public static void main(String[] args) {
        SnowflakeGenerator.setDatacenterId(1);
        SnowflakeGenerator.setMachineId(1);

        for (int i = 0; i < 10; i++) {
            long id = SnowflakeGenerator.nextId();
            System.out.println(id);
        }
    }
}

运行上面的代码,输出结果如下:

1327148530252889088
1327148530252889089
1327148530252889090
1327148530252889091
1327148530252889092
1327148530252889093
1327148530252889094
1327148530252889095
1327148530252889096
1327148530252889097

3. JWT

JSON Web Token(JWT)是一种开放标准,它定义了一种简洁的、自包含的方式,用于在不同实体之间安全地传输信息。JWT由三部分组成:头部、载荷和签名。

头部包含该JWT使用的算法(例如HMAC SHA256或RSA)以及类型(例如JWT)信息。

载荷包含要传输的数据,它可以包含任何声明,例如用户ID、过期时间等。

签名则对头部和载荷进行签名,确保它们未被篡改。

示例代码如下:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtGenerator {
    private static final String SECRET_KEY = "my_secret_key";

    public static void main(String[] args) {
        String token = createToken("123456");
        System.out.println(token);
        System.out.println(parseToken(token));
    }

    public static String createToken(String userId) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + 30 * 60 * 1000); // 30分钟后过期

        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(userId)
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public static String parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }
}

使用JWT生成和解析Token的示例代码如下:

public class JwtDemo {
    public static void main(String[] args) {
        String token = JwtGenerator.createToken("123456");
        System.out.println("Token:" + token);

        String userId = JwtGenerator.parseToken(token);
        System.out.println("UserId:" + userId);
    }
}

运行上面的代码,输出结果如下:

Token:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTYiLCJpYXQiOjE2MjkyMTM3MjYsImV4cCI6MTYyOTIxNjcyNn0.UP-GXV2X7e2BfYx7Vt3bvJMlp2Cm1blxyVcvB1n6hhQ
UserId:123456

通过上述三种方式,就可以在Java中生成唯一标识码啦!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈Java生成唯一标识码的三种方式 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java,JSP,Servlet获取当前工程路径(绝对路径)问题解析

    下面我来详细讲解“Java,JSP,Servlet获取当前工程路径(绝对路径)问题解析”的完整攻略。 问题描述 在Java Web开发中,有时需要获取当前工程(Web应用)的路径,一般是为了将文件读取到项目中,或者是为了控制输出的文件路径。本文将解决以下两个问题: 如何在Java项目中获取当前工程路径 如何在JSP和Servlet中获取当前工程路径 获取当前…

    Java 2023年6月15日
    00
  • Jquery在IE7下无法使用 $.ajax解决方法

    在IE7下使用JQuery的$.ajax方法时,可能会出现无法正常工作的问题,一般表现为无法发送请求或接收响应。这是因为IE7的XMLHttpRequest对象不支持跨域请求,而JQuery在IE7中默认使用XMLHttpRequest,导致无法正常工作。 解决这个问题的方法之一是使用IE7支持的ActiveXObject对象。具体步骤如下: 首先需要判断浏…

    Java 2023年6月15日
    00
  • Spring Security OAuth过期的解决方法

    下面是针对“Spring Security OAuth过期的解决方法”的完整攻略: Spring Security OAuth过期的解决方法 问题描述 在使用Spring Security OAuth时,有可能会遇到令牌(expired_token)过期的问题,导致无法访问受保护的资源。这时需要找到一种解决办法。 解决方法 方法一:自定义TokenServi…

    Java 2023年5月20日
    00
  • Java中的异步与线程池解读

    Java中的异步与线程池解读 什么是异步? 异步是指一个方法调用不会阻塞当前线程,而是立即返回,然后在另一个线程上执行。由于异步方法不会阻塞当前线程,所以可以提高系统的并发能力,避免系统因等待I/O等操作而造成的阻塞。 在Java中,异步通常是指使用线程池来执行一些耗时的任务。Java 5引入了java.util.concurrent包,其中提供的Excut…

    Java 2023年5月18日
    00
  • Spring MVC中使用Controller如何进行重定向

    在 Spring MVC 中,我们可以使用 Controller 进行重定向。重定向是指将用户请求重定向到另一个 URL,通常用于处理表单提交后的页面跳转。本文将详细讲解 Spring MVC 中使用 Controller 进行重定向的完整攻略,包括如何使用 RedirectAttributes 和 ModelAndView 两种方式进行重定向,并提供两个示…

    Java 2023年5月18日
    00
  • Java之Spring AOP 实现用户权限验证

    下面我就详细讲解一下“Java之Spring AOP实现用户权限验证”的完整攻略。 什么是Spring AOP Spring AOP是Spring框架的一个重要模块,它允许开发者通过声明式方式将横切关注点(如事务管理、安全控制、日志管理等)与业务逻辑代码解耦,在不修改业务逻辑代码的情况下实现这些关注点的添加。 AOP中的术语 在进行Spring AOP开发时…

    Java 2023年5月20日
    00
  • Spring获取ApplicationContext对象工具类的实现方法

    获取ApplicationContext对象是在使用Spring框架时非常常见的操作,可以方便地获取容器中的各种Bean实例。在Spring中,有多种方法可以获取ApplicationContext对象,下面给出了两种常用的方式: 方式一:通过注解@Autowried来获取ApplicationContext对象 import org.springframe…

    Java 2023年6月15日
    00
  • spring boot security设置忽略地址不生效的解决

    当我们使用Spring Boot的Security模块时,经常会遇到需要设置特定路径忽略身份验证和授权的情况,但是在设置后却发现该路径还是需要认证。本文将介绍如何解决这个问题。 问题分析 在Spring Boot中,我们可以通过WebSecurity来配置安全策略。通过调用它的ignoring()方法,可以设置忽略的URL地址。但是,有时候我们会发现这样的设…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部