我正在寻找一种生成一系列促销代码的方法。如果不是同时满足这两个要求,那将是微不足道的。它需要是一个范围(而不是将每个促销代码都保存在数据库中)以使其快速并且不可猜测,因此它不能生成像这样的代码 000-000-001, 000-000-002, 000- 000-003... 等等。
有解决这个问题的算法吗?我可以尝试使用某种散列来解决它,但尝试自己解决这个安全问题可能会使服务对我没有考虑过的漏洞开放。
我正在寻找一种生成一系列促销代码的方法。如果不是同时满足这两个要求,那将是微不足道的。它需要是一个范围(而不是将每个促销代码都保存在数据库中)以使其快速并且不可猜测,因此它不能生成像这样的代码 000-000-001, 000-000-002, 000- 000-003... 等等。
有解决这个问题的算法吗?我可以尝试使用某种散列来解决它,但尝试自己解决这个安全问题可能会使服务对我没有考虑过的漏洞开放。
我认为您的第一个要求(不将每个促销代码都保存在数据库中)是有问题的。
问题是,是否允许多次兑换一个促销代码?
如果不允许这样做,那么无论如何您都必须将已经兑换的代码存储在某个持久数据存储中,那么为什么不从一开始就将生成的代码存储在持久数据存储中,以及一个指示它是否已被兑换的标志呢?
如果您不想存储所有代码/无法存储所有代码,您仍然可以将 aRandom
与当前广告系列独有的种子一起使用:
long seed = 20190921065347L; // identifies your current campaign
Random r = new Random(seed);
for (int i = 0; i < numCodes; i++) {
System.out.println(r.nextLong());
}
或者
long seed = 20190921065347L; // identifies your current campaign
Random r = new Random(seed);
r.longs(numCodes, 100_000_000_000_000L, 1_000_000_000_000_000L)
.forEach(System.out::println);
要确定代码是否有效,您可以再次生成相同的代码:
long seed = 20190921065347L; // identifies your current campaign
Random r = new Random(seed);
System.out.println(
r.longs(numCodes, 100_000_000_000_000L, 1_000_000_000_000_000L)
.anyMatch(l -> l == 350160558695557L));
像这样的东西会起作用吗?
Random r = new Random();
long start = 1_000_000_000;
long end = 10_000_000_000L;
long n = r.longs(1, start, end).reduce(0, (a, b) -> b);
String s = String.format("%,d", n).replace(",", "-");
System.out.println(s);