生成验证工具类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace xxxxDemo
{
public class CouponCodeUtil
{
// 根据需要自行调整字符库顺序
private static readonly char[] _codePool = { 'z', 'N', 'x', '5', 'h', 'g', 'W', 'b', 'S', '4', 'q', 'X', '7', 'K', 'L', '3', 'a', 'n', 'J', 'P', 'D', 't', 'Z', 'C', 'E', 'A', 'e', 'H', 'M', 'G', 'j', 'Q', 'V', 'Y', 'w', '8', 'f', '2', 'y', 'p', 'u', 'c', 'U', 's', 'd', 'k', 'm', 'B', 'r', 'v', 'T', '6', 'F', 'R', '9' };
private static readonly int _poolSize = _codePool.Length;
// 根据需要自行调整
private static readonly int[] _weights = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
private static readonly int _weightSize = _weights.Length;
public static string HexToStr(long i)
{
StringBuilder sb = new StringBuilder();
while (i >= _poolSize)
{
long a = i % _poolSize;
i /= _poolSize;
sb.Append(_codePool[a]);
}
sb.Append(_codePool[i]);
return sb.ToString();
}
public static string GenerateCode()
{
return HexToStr(GuidToLongID());
}
public static string GenerateCodeWithParityBit()
{
string code = GenerateCode();
code += CalcParityBit(code);
return code;
}
public static char CalcParityBit(string str)
{
int sum = 0;
char[] parts = str.ToCharArray();
for (int i = 0; i < parts.Length; i++)
{
char part = parts[i];
int weight = _weights[i % _weightSize];
sum += weight * part;
}
int position = sum % _poolSize;
return _codePool[position];
}
public static bool Verify(string str)
{
string code = str.Substring(0, str.Length - 1);
char parityBit = str[str.Length - 1];
return CalcParityBit(code) == parityBit;
}
private static long GuidToLongID()
{
byte[] buffer = Guid.NewGuid().ToByteArray();
return BitConverter.ToInt64(buffer, 0);
}
}
}
使用
do
{
string coupon = CouponCodeUtil.GenerateCodeWithParityBit();
Console.WriteLine(coupon);
Console.WriteLine(CouponCodeUtil.Verify(coupon));
} while (true);
升级版
using System.Text;
namespace xxxxxx
{
public class CouponCodeUtilV2
{
private static readonly char[] _codePool = { 'z', 'N', 'x', '5', 'h', 'g', 'W', 'b', 'S', '4', 'q', 'X', '7', 'K', 'L', '3', 'a', 'n', 'J', 'P', 'D', 't', 'Z', 'C', 'E', 'A', 'e', 'H', 'M', 'G', 'j', 'Q', 'V', 'Y', 'w', '8', 'f', '2', 'y', 'p', 'u', 'c', 'U', 's', 'd', 'k', 'm', 'B', 'r', 'v', 'T', '6', 'F', 'R', '9' };
private static readonly int _poolSize = _codePool.Length;
private static readonly int[] _weights = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
private static readonly int _weightSize = _weights.Length;
public static string GenerateCode()
{
long uniqueId = BitConverter.ToInt64(Guid.NewGuid().ToByteArray(), 0);
StringBuilder codeBuilder = new StringBuilder();
int sum = 0;
int position = -1;
char currentChar;
int weight;
while (uniqueId >= _poolSize)
{
long poolPosition = uniqueId % _poolSize;
uniqueId /= _poolSize;
currentChar = _codePool[poolPosition];
codeBuilder.Append(currentChar);
position++;
weight = _weights[position % _weightSize];
sum += weight * currentChar;
}
currentChar = _codePool[uniqueId];
codeBuilder.Append(currentChar);
position++;
weight = _weights[position % _weightSize];
sum += weight * currentChar;
position = sum % _poolSize;
codeBuilder.Append(_codePool[position]);
return codeBuilder.ToString();
}
public static bool Verify(string code)
{
if (string.IsNullOrWhiteSpace(code) || code.Length < 2) return false;
char[] parts = code.ToCharArray();
int sum = 0;
int weight;
char part;
for (int i = 0; i < parts.Length - 1; i++)
{
part = parts[i];
weight = _weights[i % _weightSize];
sum += weight * part;
}
int position = sum % _poolSize;
return parts[parts.Length - 1] == _codePool[position];
}
}
}
使用
var code = CouponCodeUtilV2.GenerateCode();
var verify = CouponCodeUtilV2.Verify(code);
Console.WriteLine($"{code}\t{verify}");