1.需求
要求是很简单的,每个验证码的有效时间是2小时
,这个并不是收到验证码开始计时的,而是每个两小时的时间段使用的是相同的验证码。
2.代码实现
2.1 依赖
<dependency> <groupId>gov.nist.math</groupId> <artifactId>jama</artifactId> <version>1.0.3</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.6</version> </dependency>
2.2 时间参数处理方法
将2个小时处理为相同的值
:
@Slf4j public class VerificationCodeUtil { /** * 时间字符串 * * @param dateStr yyyy-MM-dd HH:mm:ss */ public static String getCode(String dateStr) { int dataStrLength = 13; try { if (dateStr.length() >= dataStrLength) { String yearMonthDay = dateStr.substring(0, 10); int hour = Integer.parseInt(dateStr.substring(11, 13)); int twoHour = 2; if (hour % twoHour != 0) { hour--; } String md5Str = DigestUtils.md5Hex("vc#" + yearMonthDay + hour); return getCodeByMd5(md5Str); } else { log.error("dateStr [{}] not match format [yyyy-MM-dd HH:mm:ss]!", dateStr); } } catch (Exception e) { e.printStackTrace(); log.error("dateStr [{}] not match format [yyyy-MM-dd HH:mm:ss]!", dateStr); } return dateStr; } }
2.3 截取验证码方法
@Slf4j public class VerificationCodeUtil { // 对指定字符串生成验证码 private static String getCodeByMd5(String md5Str) { try { byte[] md5 = md5Str.getBytes(); double[][] preMatrix = new double[4][8]; for (int j = 0; j < 4; j++) { for (int k = 0; k < 8; k++) { preMatrix[j][k] = md5[j * 8 + k]; } } Matrix matrix = new Matrix(preMatrix); Matrix matrix1 = matrix.getMatrix(1, 2, 2, 5); Matrix matrix2 = matrix.transpose(); Matrix matrix21 = matrix2.getMatrix(0, 3, 0, 3); Matrix matrix22 = matrix2.getMatrix(4, 7, 0, 3); Matrix matrix3 = matrix21.plus(matrix22); Matrix result = matrix1.times(matrix3); double[][] re = result.getArray(); StringBuilder str = new StringBuilder(); for (double[] doubles : re) { for (double aDouble : doubles) { int a = (int) aDouble % 16; str.append(Integer.toHexString(a)); } } return str.toString().toUpperCase(); } catch (Exception e) { e.printStackTrace(); return null; } } }
2.4 验证方法
@Slf4j public class VerificationCodeUtil { public static void main(String[] args) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); DateTime parse = DateUtil.parse("2023-11-09 23:59:59", "yyyy-MM-dd HH:mm:ss"); String format = df.format(parse); System.out.println(getCode(format)); // 00:00 3A756DFC // 00:59 3A756DFC // 01:59 3A756DFC // 01:59 3A756DFC // 02:00 9E937D4B // 02:59 9E937D4B // 03:00 9E937D4B // 22:00 D014DD79 // 23:59 D014DD79 } }
3.总结
很简单的算法分享。优点:
- 不需要将生成的验证码缓存。
- 时间入参,能够重复获取相同的值。