部分功能的实现和算法

news2024/9/19 22:04:59

目录

1.雪花算法

2.MD5加密

3.小眼睛显示密码

4.发送验证码

5.倒计时


1.雪花算法

SnowFlake 中文意思为雪花,故称为雪花算法。最早是 Twitter 公司在其内部用于分布式环境下生成唯一 ID。在2014年开源 scala 语言版本

雪花算法的原理就是生成一个的 64 位比特位的 long 类型的唯一 id。

最高 1 位固定值 0,因为生成的 id 是正整数,如果是 1 就是负数了。
接下来 41 位存储毫秒级时间戳,2^41/(1000*60*60*24*365)=69,大概可以使用 69 年。
再接下 10 位存储机器码,包括 5 位 datacenterId 和 5 位 workerId。最多可以部署 2^10=1024 台机器。
最后 12 位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。即对于同一台机器而言,同一毫秒时间戳下,可以生成 2^12=4096 个不重复 id。

public class SnowflakeIdGenerator {

    private final long twepoch = 1626708222000L; // 设置起始时间戳,这里使用当前时间的毫秒值作为起始时间
    private final long workerIdBits = 10L;
    private final long sequenceBits = 12L;

    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
    private final long workerIdShift = sequenceBits;
    private final long timestampLeftShift = sequenceBits + workerIdBits;
    private final long sequenceMask = -1L ^ (-1L << sequenceBits);

    private long workerId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;

    public SnowflakeIdGenerator(long workerId) {
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("Worker ID can't be greater than %d or less than 0", maxWorkerId));
        }
        this.workerId = workerId;
    }

    public synchronized long nextId() {
        long timestamp = timeGen();

        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds");
        }

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

        lastTimestamp = timestamp;

        return ((timestamp - twepoch) << timestampLeftShift) |
                (workerId << workerIdShift) |
                sequence;
    }

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

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

    // 示例用法
    public static void main(String[] args) {
        SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1); // 假设当前机器的worker id是1

        // 生成10个ID进行展示
        for (int i = 0; i < 10; i++) {
            long id = idGenerator.nextId();
            System.out.println("Generated Id: " + id);
        }
    }
}

2.MD5加密

MD5加密全程是Message-Digest Algoorithm 5(信息-摘要算法),它对信息进行摘要采集,再通过一定的位运算,最终获取加密后的MD5字符串。
  例如我们要加密一篇文章,那么我们会随机从每段话或者每行中获取一个字,把这些字统计出来后,再通过一定的运算获得一个固定长度的MD5加密后信息。因此,其很难被逆向破解。

MD5加密的特点:

MD5加密的特点主要有以下几点:
  1、针对不同长度待加密的数据、字符串等等,其都可以返回一个固定长度的MD5加密字符串。(通常32位的16进制字符串);
  2、其加密过程几乎不可逆,除非维护一个庞大的Key-Value数据库来进行碰撞破解,否则几乎无法解开。
  3、运算简便,且可实现方式多样,通过一定的处理方式也可以避免碰撞算法的破解。
  4、对于一个固定的字符串。数字等等,MD5加密后的字符串是固定的,也就是说不管MD5加密多少次,都是同样的结果。

public class MD5Util {

    // 加密方法:接收一个字符串明文,返回使用 MD5 加密后的哈希值
    public static String encrypt(String plaintext) throws NoSuchAlgorithmException {
        // 使用 MD5 算法创建 MessageDigest 对象
        MessageDigest md = MessageDigest.getInstance("MD5");
        // 更新 MessageDigest 对象中的字节数据
        md.update(plaintext.getBytes());
        // 对更新后的数据计算哈希值,存储在 byte 数组中
        byte[] digest = md.digest();
        // 将 byte 数组转换为十六进制字符串
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }
        // 返回十六进制字符串
        return sb.toString();
    }

    // 解密方法:接收一个字符串明文和一个使用 MD5 加密后的哈希值,返回解密结果(true 表示匹配,false 表示不匹配)
    public static boolean decrypt(String plaintext, String encrypted) throws NoSuchAlgorithmException {
        // 调用加密方法计算出明文的哈希值
        String decrypted = encrypt(plaintext);
        // 比较计算得到的哈希值和输入的哈希值是否相同
        return decrypted.equals(encrypted);
    }
}

3.小眼睛显示密码

方法:javafx中添加一个密码文本框(passwordFild),一个普通文本框(passwordlook),一个按钮(yanjingButton),两张图片(eyesz)(eyesb),按钮和两张图片位置重叠,按钮透明,睁眼的图片透明,闭眼的图片显示,设置按钮点击方法(yanjingButtonOnAction)如下。点击切换图片的透明和显示,切换两个文本框的透明与显示。


    // 在类的成员变量中添加一个标志,用于记录是否已经绑定过文本框
    private boolean isPasswordFieldsBound = false;
    //小眼睛
    public void yanjingButtonOnAction(ActionEvent actionEvent) {
        Button eyesButton = (Button) actionEvent.getSource();
        // 初始化绑定操作,只需执行一次
        if (!isPasswordFieldsBound) {
            passwordlook.textProperty().bindBidirectional(passwordField.textProperty());
            isPasswordFieldsBound = true;
        }
        eyesButton.setOnMouseClicked(event -> {
            String look = passwordField.getText();
            passwordField.setText(look);
            boolean isPasswordFieldVisible = passwordField.isVisible();
            passwordField.setVisible(!isPasswordFieldVisible);
            passwordlook.setVisible(isPasswordFieldVisible);
            eyesb.setVisible(!isPasswordFieldVisible);
            eyesz.setVisible(isPasswordFieldVisible);
        });
    }

4.发送验证码

注意:邮箱用自己的

同时想要如下导包:

发送验证码:

import java.util.Date;
import java.util.Properties;
import java.util.Random;
import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;


public class MailUtils {
    private static MimeMessage message;
    private static String m;

      public MailUtils() {
      }

      public static String sendEmail(String to) throws MessagingException {

          String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
          // QQ邮箱服务器
          String smtpHost = "smtp.qq.com";
          // 邮箱用户名,即QQ账号(自定义)
          String username = "2161672768";
          // 邮箱授权码(自定义)
          String password = "xbgwgdzxkqobdjih";
          // 自己的邮箱(自定义)
          String from = "2161672768@qq.com";
          // 要发送的邮箱地址(自定义)
          String toAddress = to;

          //Transport transport;
          Properties props = new Properties();
          props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
          props.setProperty("mail.smtp.socketFactory.fallback", "false");
          props.setProperty("mail.smtp.port", "465");
          props.setProperty("mail.smtp.socketFactory.port", "465");
          props.setProperty("mail.smtp.auth", "true");
          props.put("mail.smtp.host", smtpHost);
          props.put("mail.smtp.username", username);
          props.put("mail.smtp.password", password);
          Session session = Session.getDefaultInstance(props, new Authenticator() {
              protected PasswordAuthentication getPasswordAuthentication() {
                  return new PasswordAuthentication(username, password);
              }
          });
         InternetAddress[] addresses = new InternetAddress[]{new InternetAddress(toAddress)};
          message = new MimeMessage(session);
          message.setFrom(new InternetAddress(from));
          message.setRecipients(MimeMessage.RecipientType.TO, addresses);
          message.setSubject("验证码");
          message.setSentDate(new Date());
          m = generateVerificationCode(5);
          message.setText(m);
          System.out.println(m);
          Transport  transport = session.getTransport("smtp");
          transport.connect(smtpHost, username, password);
          transport.sendMessage(message, message.getAllRecipients());
        //  Transport.send(message);
          System.out.println("信息已经发送");
          transport.close();
          return m;
      }

      public static boolean judge(String s) {
          return m.equals(s);
      }

      //随机生成长度为5的验证码
      private static String generateVerificationCode(int length) {
          String charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
          StringBuilder verificationCode = new StringBuilder();
          Random random = new Random();

          for(int i = 0; i < length; ++i) {
              verificationCode.append(charSet.charAt(random.nextInt(charSet.length())));
          }

          return verificationCode.toString();
      }
  }

结果如下:

5.倒计时

在发送验证码后,用于显示等待用户再次发送验证码的剩余时间,这里设置的是60s(注意:1000L=1s)
 //在发送验证码后,用于显示等待用户再次发送验证码的剩余时间,60s
    public void count(){
        this.yzmButton.setVisible(false);
        this.wait.setVisible(true);
        (new Thread(() -> {
            int st = 60;

            while(st > 0) {
                final int finalSt = st;
                Platform.runLater(new Runnable() {
                    public void run() {
                        EmailLoginController.this.wait.setText(Integer.toString(finalSt));
                    }
                });

                try {
                    Thread.sleep(1000L);
                    --st;
                } catch (InterruptedException var4) {
                    InterruptedException e = var4;
                    throw new RuntimeException(e);
                }
            }

            this.yzmButton.setVisible(true);
            this.wait.setVisible(false);
        })).start();
    }

方法用于实现较长时间的倒计时,这里设置的是120秒,用于显示验证码的有效时间。
  //方法用于实现较长时间的倒计时(120秒),用于显示验证码的有效时间。
    public void count00(){
        this.time.setVisible(true);
        (new Thread(() -> {
            int st = 120;

            while(st > 0) {
                if (this.time1 != this.time2) {
                    this.time1 = this.time2;
                    st = 120;
                }

                final int finalSt = st;
                Platform.runLater(new Runnable() {
                    public void run() {
                       EmailLoginController.this.time.setText("验证码有效时间剩余:" + Integer.toString(finalSt));
                    }
                });

                try {
                    Thread.sleep(1000L);
                    --st;
                } catch (InterruptedException var4) {
                    InterruptedException e = var4;
                    throw new RuntimeException(e);
                }
            }

            this.time.setVisible(false);
        })).start();
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1940564.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索XEX数字资产交易的优势与操作指南

随着数字资产市场的快速发展&#xff0c;越来越多的投资者开始关注并参与其中。XEX交易所作为一个新兴的数字资产交易平台&#xff0c;以其用户友好的界面和高效的交易服务&#xff0c;迅速吸引了大量用户。本文将介绍XEX数字资产交易的主要特点和优势&#xff0c;帮助新手更好…

昇思25天学习打卡营第18天|munger85

DCGAN生成漫画头像 首先肯定是下载训练数据&#xff0c;而这些训练数据就是一些卡通头像。后来我们会看到这个具体的头像 就像其他的数据集目录一样&#xff0c;它是由一些目录和这个目录下面的文件组成的数据集。 有相当多的图片。所以可以训练出来比较好的效果。 图片的处理…

Python应用开发——30天学习Streamlit Python包进行APP的构建(20):配置

Configuration配置 config.toml config.toml 是一个可选文件,你可以为工作目录或全局开发环境定义它。当 config.toml 文件同时在全局和工作目录中定义时,Streamlit 会合并配置选项,并优先使用工作目录配置。此外,你还可以使用环境变量和命令行选项来覆盖其他配置选项。更…

PySide(PyQt),使用 QGraphicsOpacityEffect 设置小部件的整体显示透明度

基本的demo 在 PySide6 中&#xff0c;可以使用 QGraphicsOpacityEffect 类来实现整体显示透明度。下面是一个简单的示例&#xff0c;演示了如何为 QLabel 设置透明度&#xff1a; from PySide6.QtWidgets import QApplication, QLabel, QGraphicsOpacityEffect, QVBoxL…

Java--接口

目录 语法规则 例子 实现多个接口 接口之间的继承 抽象类和接口的区别 接口使用实例--Comparable接口 Clonable接口 浅拷贝 深拷贝 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;电源插座&#xff0c;主机上的USB接口等。这些插口中可以插…

【C++】位运算:两整数之和

1.题目 2.算法思路 本题不能只用 -&#xff0c;那大概率用到位运算符。 异或的作用是无进位相加&#xff0c;所以需要通过异或运算&#xff08;^&#xff09;来替代加法运算&#xff0c;但是我们无法确定进位的信息。所以需要与运算&#xff08;&&#xff09;来得到进位的…

【数据结构与算法 经典例题】翻转二叉树

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法 经典例题》C语言 期待您的关注 ​ 目录 一、问题描述 二、解题思路 三、C语言实现代码 一、问题描述 给你一…

golang 字符编码 gbk/gb2312 utf8编码相互转换,判断字符是否gbk编码函数, 字符编码转换基础原理解析, golang默认编码utf8

虽然golang里面的默认编码都是统一的unicode utf8编码&#xff0c; 但是我们在调用外部系统提供的api时&#xff0c;就可能会遇到别人的接口提供的编码非 utf8编码&#xff0c;而是gbk/gb2312编码&#xff0c; 这时候我们就必须要将别人的gbk编码转换为go语言里面的默认编码ut…

2024国内AI公司50强榜单。。。

你好&#xff0c;我是郭震 近日&#xff0c;2024国内AI公司50强榜单发布。 1 AI公司50强榜单 AI公司排名前五分别是&#xff1a;百度&#xff0c;阿里&#xff0c;华为&#xff0c;腾讯&#xff0c;科大讯飞。 6-10名分别是&#xff1a;小米&#xff0c;商汤&#xff0c;字节跳…

Jeston Orin IIC 驱动测试 —— 以MPU6050为例

前言 后续驱动需要需要使用IIC作为通讯的协议&#xff0c;但是做的板子还没来&#xff0c;因此&#xff0c;在开发板驱动加载真正的之前&#xff0c;我们需要确保IIC能够正常通信。 网上的博客基本都是教怎么使用i2c-tools进行通信的&#xff0c;但是这种方法只是在用户空间下…

【效率提升】程序员常用Shell脚本

文章目录 常用Shell脚本一. 定期更新分区数据二、获取系统资源的使用情况 常用Shell脚本 一. 定期更新分区数据 在某些场景下&#xff0c;我们需要对N年前某一分区的数据进行删除&#xff0c;并添加今年该对应分区的数据&#xff0c;实现数据的流动式存储。 #!/bin/bash dt$…

基于FPGA的数字信号处理(18)--半加器和全加器

前言 在数字系统中&#xff0c;加法运算是最常见的算术运算&#xff0c;同时它也是进行各种复杂运算的基础。 半加器 最简单的加法器叫做 半加器&#xff08;Half Adder&#xff09;&#xff0c;它将2个输入1bit的数据相加&#xff0c;输出一个2bits的和&#xff0c;和的范围为…

若依前后端获取当前用户

后端 Autowired private TokenService tokenService;LoginUser loginUser tokenService.getLoginUser(); sysInquiry.setCreateBy(loginUser.getUsername()); sysInquiry.setCreateTime(DateUtils.getNowDate()); 前端 获取使用 const nickName this.$store.state.user.nick…

最大似然估计模型及 Stata 具体操作步骤

目录 一、引言 二、理论原理 三、准备数据 四、定义似然函数 五、进行最大似然估计 六、代码解释 七、代码运行结果 八、模型评估与诊断 一、引言 最大似然估计&#xff08;Maximum Likelihood Estimation&#xff0c;MLE&#xff09;是一种在统计学中广泛应用的参数估计…

linux下磁盘分区工具GParted

最近发现安装的redhat机器部分磁盘大小分配不合理 使用gpated对磁盘重新分区 1、使用U盘制作一个启动盘 下载启动盘制作工具Index of /downloads 使用非常简单&#xff0c;选择gparted-live-1.1.0-3-i686.iso包即可 2、制作完成后&#xff0c;重启机器&#xff0c;选择U盘…

黑马点评-Postman卡住sending Requst原因解决

不知道为什么&#xff0c;用这个c1e1d5的token就会一直卡死&#xff0c;但是换了一个token就解决了&#xff0c;目前不知道为什么 解决了&#xff0c;原来是这个请求下面的函数发生了死循环&#xff01;&#xff01;太瓜皮了我超&#xff01; 把num写成了count&#xff0c;导…

Docker启动PostgreSql并设置时间与主机同步

在 Docker 中启动 PostgreSql 时&#xff0c;需要配置容器的时间与主机同步。可以通过在 Dockerfile 或者 Docker Compose 文件中设置容器的时区&#xff0c;或者使用宿主机的时间来同步容器的时间。这样可以确保容器中的 PostgreSql 与主机的时间保持一致&#xff0c;避免在使…

【iOS】Tagged Pointer

目录 前言什么是Tagged Pointer&#xff1f;引入Tagged Pointer技术之前引入Tagged Pointer之后总结 Tagged Pointer原理&#xff08;TagData分析&#xff09;关闭数据混淆MacOS分析NSNumberNSString iOS分析 判断Tagged PointerTagged Pointer应用Tagged Pointer 注意点 Tagge…

[MySQL][深入理解隔离性][上][MVCC]详细讲解

目录 0.铺垫1.初识MVCC2.三个记录隐藏列字段1.是什么&#xff1f;2.示例 3.undo日志4.模拟MVCC5.思考 0.铺垫 在RR级别的时候&#xff0c;多个事务的update&#xff0c;多个事务的insert&#xff0c;多个事务的delete&#xff0c;是否会有加锁现象&#xff1f; 现象结果是&…

【C++】deque以及优先级队列

容器适配器 deque的介绍deque的原理介绍 priority_queue的介绍与使用priority_queue的介绍priority_queue的使用constructor&#xff08;构造函数&#xff09;emptypushpoptopsize priority_queue的模拟实现 仿函数何为适配器容器适配器deque的缺陷选择deque作为适配器的理由ST…