序列号生成-模拟windows office序列号

最近看到office2013在提示过期问题(升级win10后遗症),就想到模拟下office的激活码。~~

 

起初想到应该简单,最后越试越复杂。所以就记录下,毕竟花费了时间。

 

 

package test;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class SerialNum {

	//随机器,随机次数和符号等。
	private static Random r = new Random();
	
	//定义一些数字取值范围过滤,避免数字字母看起来混淆的问题,还有,避免暴力全遍历的问题。
	private static List<Integer> numFilter = new ArrayList<>();

	//定义一些字符取值范围过滤
	private static List<Integer> charFilter = new ArrayList<>();

	//初始化
	static {
		numFilter.add(0);
		numFilter.add(1);
		numFilter.add(5);

		charFilter.add(97);// a
		charFilter.add(65);
		charFilter.add(101);// e
		charFilter.add(69);
		charFilter.add(105);// i
		charFilter.add(73);
		charFilter.add(108);// l
		charFilter.add(76);
		charFilter.add(111);// o
		charFilter.add(79);
		charFilter.add(115);// s
		charFilter.add(83);
		charFilter.add(117);// u
		charFilter.add(85);
		charFilter.add(122);// z
		charFilter.add(90);
	}

	//main函数,批量生成多组
	public static void main(String[] args) {
		int i = 0;
		while (i < 10) {
			outSerialNum(5,5);
			i++;
		}
	}

	//获取一组序列,入参为序列有几组,每组长度为几
	private static void outSerialNum(int group,int len) {
		long start = System.currentTimeMillis();

		StringBuilder s = new StringBuilder();

		// 以随机串的分组数量为单位,获取每组的串
		for (int i = 0; i < group; i++) {
			// 传入每组串的长度
			s.append(getRandomStr(len) + "-");
		}
		System.out.println(s.toString().substring(0, s.length()-1));
		System.out.println("cost:" + (System.currentTimeMillis() - start));
	}

	// 获取一组长度为n的随机数字字母串
	private static String getRandomStr(int len) {
		StringBuilder sb = new StringBuilder();
		String[] unit = new String[len];
		// 随机出数字和字母出现的次数,保证数字和字母至少出现一次
		int numCount = r.nextInt(len);
		if (numCount == 0) {
			numCount = 1;
		}
		int charCount = len - numCount;

		// System.out.println("numCount=" + numCount + "; charCount=" +
		// charCount);

		// 获取二者中出现次数多的类型,优先随机插入数组
		int max = numCount;
		int flag = 0;// 表示数字类型
		if (charCount > numCount) {
			max = charCount;
			flag = 1;// 字母
		}

		// 优先随机位置插入出现次数多的类型
		for (int i = 0; i < max; i++) {
			int f = r.nextInt(len);
			if (flag == 0) {
				unit[f] = String.valueOf(getNum());
			} else {
				unit[f] = String.valueOf(getChar());
			}
		}

		// System.out.println("优先插入次数多的类型后:" + getArrayString(unit));

		// 遍历数组,如果不为空,加入已经存在的字符串;为空,字符串填充另一种类型
		for (String s : unit) {
			if (null == s) {
				// 与第一次插入采用相反的类型
				if (flag == 0) {
					sb.append(String.valueOf(getChar()));
				} else {
					sb.append(String.valueOf(getNum()));
				}
			} else {
				sb.append(s);
			}
		}
		return sb.toString();
	}

	private static int getNum() {
		int n = r.nextInt(10);
		return numFilter.contains(n) ? getNum() : n;// 不能在数字过滤器中
	}

	private static char getChar() {
		int c = r.nextInt(26) + 97;
		// 不能在字符过滤器中
		return charFilter.contains(c) ? getChar() : (char) c;
	}

}

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值