最近做了一个这样的需求,系统有一部分vip用户不需要普通用户购买,而是公司统一购买兑换码,公司员工输入自己的兑换码,如果兑换码正确的话,自动升级为vip用户,兑换码要数字和大写字母,不能重复,这里记录一个现场的工具类

package com.leliven.washcar.member.util;import cn.hutool.core.util.RandomUtil;import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** 激活码生成工具** @author ycf* @since 2021-12-21*/
public class ActivationCodeUtil {static String stringTable = "ABCDEFGHIJKMNPQRSTUVWXYZ23456789";final static String password = "dak3le2";//从byte转为字符表索引所需要的位数final static int convertByteCount = 5;public static void main( String[] args ) throws Exception {// System.out.println(RandomUtil.randomInt(1, 100));ShowTime();System.out.println("=======================");create((byte) RandomUtil.randomInt(1,100),10,12,password);VerifyCode("2CZNXWNM2KZA");VerifyCode("HIYGXFWM74MA");VerifyCode("CUT2W36ICK4A");VerifyCode("M3MKCPJFMBVA");VerifyCode("M3MKCPJFMTVA");}/*** 生成兑换码* 这里每一次生成兑换码的最大数量为int的最大值即2147483647* @return*/public static List<String> create(byte groupId, int codeCount, int codeLength, String password) {List<String> codes = new ArrayList<>();//8位的数据总长度int fullCodeLength = codeLength * convertByteCount / 8;//随机码对时间和id同时做异或处理//类型1,id4,随机码n,校验码1 int randCount = fullCodeLength - 6;//随机码有多少个//如果随机码小于0 不生成if(randCount <= 0 ) {return codes;}for(int i = 0 ; i < codeCount ; i ++) {//这里使用i作为code的id//生成n位随机码byte[] randBytes = new byte[randCount];for(int j = 0 ; j  < randCount ; j ++) {randBytes[j] = (byte)(Math.random() * Byte.MAX_VALUE);}//存储所有数据ByteHelper byteHelper = ByteHelper.CreateBytes(fullCodeLength);byteHelper.AppendNumber(groupId).AppendNumber(i).AppendBytes(randBytes);//计算校验码 这里使用所有数据相加的总和与byte.max 取余byte verify = (byte) (byteHelper.GetSum() % Byte.MAX_VALUE);byteHelper.AppendNumber(verify);//使用随机码与时间和ID进行异或for(int j = 0 ; j < 5 ; j ++) {byteHelper.bytes[j] = (byte) (byteHelper.bytes[j] ^ (byteHelper.bytes[5 + j % randCount]));}//使用密码与所有数据进行异或来加密数据byte[] passwordBytes = password.getBytes();for(int j = 0; j < byteHelper.bytes.length ; j++){byteHelper.bytes[j] = (byte) (byteHelper.bytes[j] ^ passwordBytes[j % passwordBytes.length]);}//这里存储最终的数据byte[] bytes = new byte[codeLength];//按6位一组复制给最终数组for(int j = 0; j < byteHelper.bytes.length ; j ++) {for(int k = 0 ; k < 8 ; k ++) {int sourceIndex = j*8+k;int targetIndex_x = sourceIndex / convertByteCount;int targetIndex_y = sourceIndex % convertByteCount;byte placeVal = (byte)Math.pow(2, k);byte val = (byte)((byteHelper.bytes[j] & placeVal) == placeVal ? 1:0);//复制每一个bitbytes[targetIndex_x] = (byte)(bytes[targetIndex_x] | (val << targetIndex_y));}}StringBuilder result = new StringBuilder();//编辑最终数组生成字符串for(int j = 0 ; j < bytes.length ; j ++) {result.append(stringTable.charAt(bytes[j]));}codes.add(result.toString());}ShowTime();return codes;}/*** 验证兑换码* @param code*/public static boolean VerifyCode(String code ){byte[] bytes = new byte[code.length()];//首先遍历字符串从字符表中获取相应的二进制数据for(int i=0;i<code.length();i++){byte index = (byte) stringTable.indexOf(code.charAt(i));bytes[i] = index;}//还原数组int fullCodeLength = code.length() * convertByteCount / 8;int randCount = fullCodeLength - 6;//随机码有多少个byte[] fullBytes = new byte[fullCodeLength];for(int j = 0 ; j < fullBytes.length ; j ++) {for(int k = 0 ; k < 8 ; k ++) {int sourceIndex = j*8+k;int targetIndex_x = sourceIndex / convertByteCount;int targetIndex_y = sourceIndex % convertByteCount;byte placeVal = (byte)Math.pow(2, targetIndex_y);byte val = (byte)((bytes[targetIndex_x] & placeVal) == placeVal ? 1:0);fullBytes[j] = (byte) (fullBytes[j] | (val << k));}}//解密,使用密码与所有数据进行异或来加密数据byte[] passwordBytes = password.getBytes();for(int j = 0 ; j < fullBytes.length ; j++){fullBytes[j] = (byte) (fullBytes[j] ^ passwordBytes[j % passwordBytes.length]);}//使用随机码与时间和ID进行异或for(int j = 0 ; j < 5 ; j ++) {fullBytes[j] = (byte) (fullBytes[j] ^ (fullBytes[5 + j % randCount]));}//获取校验码 计算除校验码位以外所有位的总和int sum = 0;for(int i = 0 ;i < fullBytes.length - 1; i ++){sum += fullBytes[i];}byte verify = (byte) (sum % Byte.MAX_VALUE);//校验if(verify == fullBytes[fullBytes.length - 1]){System.out.println(code + " : verify success!");return true;}else {System.out.println(code + " : verify failed!");return false;}}public static void ShowTime(){Date date = new Date();long times = date.getTime();//时间戳System.out.println("time  : " + times);}
}

辅助工具类:

package com.leliven.washcar.member.util;public class ByteHelper {//原始数组byte[] bytes;//记录当前写入到多少位int index;private ByteHelper(int capacity){bytes = new byte[capacity];index = 0;}public static ByteHelper CreateBytes(int capacity){ByteHelper byteHelper = new ByteHelper(capacity);return byteHelper;}//向数组中追加内容public ByteHelper AppendNumber(long val){byte[] arr = Number2byte(val);AppendBytes(arr);return this;}public ByteHelper AppendNumber(int val){byte[] arr = Number2byte(val);AppendBytes(arr);return this;}public ByteHelper AppendNumber(short val){byte[] arr = Number2byte(val);AppendBytes(arr);return this;}public ByteHelper AppendNumber(byte val){byte[] arr = new byte[]{val};AppendBytes(arr);return this;}/*** 获取数据的总和* @return*/public int GetSum(){int ret = 0;for(int i = 0 ; i < bytes.length ; i ++){ret += bytes[i];}return ret;}//追加byte数组public ByteHelper AppendBytes(byte[] arr){for(byte i = 0 ; i < arr.length ; i ++){bytes[index + i] = arr[i];}index += arr.length;return this;}/*** 将数字转换为byte数组*/public static byte[] Number2byte(long val) {byte[] arr = new byte[]{(byte) ((val >> 56) & 0xFF),   (byte) ((val >> 48) & 0xFF),      (byte) ((val >> 40) & 0xFF),         (byte) ((val >> 32) & 0xFF), (byte) ((val >> 24) & 0xFF),   (byte) ((val >> 16) & 0xFF),      (byte) ((val >> 8) & 0xFF),      (byte) (val & 0xFF)  };return arr;}public static byte[] Number2byte(int val) {byte[] arr = new byte[]{(byte) ((val >> 24) & 0xFF),   (byte) ((val >> 16) & 0xFF),      (byte) ((val >> 8) & 0xFF),      (byte) (val & 0xFF)   };return arr;}public static byte[] Number2byte(short val) {byte[] arr = new byte[]{     (byte) ((val >> 8) & 0xFF),      (byte) (val & 0xFF)     };return arr;}
}

vip激活码、兑换码生成工具类,支持校验相关推荐

  1. 微信小程序二维码生成工具,后端二维码生成工具类。

    微信小程序开发二维码生成工具类 前言 业务背景 设计思路 具体实现 接下来我们进行工具的改造 前言 或许这是你搜寻的第n篇文章来解决你项目中的问题,虽然我不能去替你完全适配你的业务需求,但是我可以给你 ...

  2. 二维码 生成工具类(文件转Base64字符串,Base64字符串转文件)

    希望我的知识榨干了能帮到你解除困难,要是没有帮助你的,问度娘和知爹 一.POM.xml依赖下载 二.工具类提供 一.POM.xml依赖下载 <!-- 生成二维码依赖 --><depe ...

  3. Java:二维码生成工具类

    java 二维码生成工具类 需要引入的maven <!--Java 生成二维码 --> <dependency><groupId>com.google.zxing& ...

  4. 好用的对象转xml、xml转对象工具类-支持集合嵌套转换(Java实现)

    好用的对象转xml.xml转对象工具类-支持集合嵌套转换(Java实现) 网上找了很多转换工具,对于自己的业务都不是很合适,所以总结了一下网上的方案,最终定下来是这样子的,主要使用dom4j做操作 m ...

  5. 条形码生成工具类实现

    1.pom引用: <!-- 条形码工具类 --> <dependency><groupId>com.google.zxing</groupId>< ...

  6. java二维码的生成工具

    java二维码的生成工具 1.导入jar包,我是用的是一个谷歌提供的 <dependency><groupId>com.google.zxing</groupId> ...

  7. java 图形校验_java图形验证码生成工具类 web页面校验验证码

    java图形验证码生成工具类 web页面校验验证码 发布于 2020-7-14| 复制链接 摘记: 最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善.验证码生成器: ```java i ...

  8. java图形验证码生成工具类

    转载自   java图形验证码生成工具类 生成验证码效果       ValidateCode.java 验证码生成类 package cn.dsna.util.images; import java ...

  9. mybatis-plus使用 generator 代码生成器生成实体类支持Swagger2

     作者:传说中的黑桃A blog.csdn.net/sj13074480550/article/details/102976146 mybatis-plus使用generator代码生成器生成实体类支 ...

最新文章

  1. 【廖雪峰python进阶笔记】定制类
  2. SQL Server 2012入门T-SQL基础篇:(1)环境准备
  3. 使用visual vm 分析线程(上)
  4. 现宣布Windows Azure中SQL数据同步的增强功能
  5. python 代码-代码的重试机制(python简单实现)
  6. fineUI表格控件各属性说明
  7. python -- 进程
  8. mysql怎么维护_Navicat for MySQL 如何管理和维护表
  9. VTK:可视化之LabeledDataMapper
  10. 在MAC下安装一些软件时提示来自身份不明开发者
  11. win10休眠设置_电脑总是“打瞌睡”?教你如何简单关闭自动休眠
  12. [react] 什么是浅层渲染?
  13. DNS 反向解析出错 Error in named configuration: zone centos.vbird/IN: loaded serial 2011080401
  14. Linux下的Asp.Net配置指南
  15. 红帽学习笔记[RHCSA] 第一周
  16. wps linux 字体目录在哪个文件夹,WPS OFFICE怎么添加字体?(我下载的字体文件应当放那个文件夹?)...
  17. 需求调研第二篇--调研准备阶段避免哪些错误
  18. IOS 发展史各个ipone的发布时间(二)
  19. Freeway:Maximizing MLP for Slice-Out-of-Order Execution
  20. Unity2D—骨骼绑定、IK系统、动画(一)

热门文章

  1. 怎样屏蔽微信朋友圈视频?局域网如何禁止员工看朋友圈视频?
  2. 财经365热点:牛股票层出不穷 基金提前“埋伏”获丰收
  3. 程万云:做淘宝客需要思考和实践还要有成功的欲望 .
  4. 【操作系统】RR算法(时间片轮转,假设时间片q=1)
  5. java 二元一次方程式_怎样用java觖二元一次方程
  6. 使用Topshelf部署.net core windows服务
  7. 2021FME博客大赛 —— FME在年度重要地理信息更新中的应用
  8. 计算机考研统考科目408思维导图
  9. Manjaro尝鲜体验
  10. 入手ZeroNet,我的站吼吼