.NET快速生成快递柜唯一取件码

曾管理一万多台快递柜,优化了系统中生成唯一取件码的算法。

项目:https://github.com/nnhy/PickupCode

新建项目,添加 Nuget 应用 NewLife.Redis ,借助其Add去重能力。

代码如下:.

private static void Main(string[] args){    XTrace.UseConsole();
    var redis = new FullRedis("127.0.0.1", null, 3);
    var stationCode = "2743";    for (int i = 0; i < 8; i++)    {        var code = BuildPickupCode(redis, stationCode);        XTrace.WriteLine("取件码{0}:{1}", i + 1, code);    }}
/// <summary>为站点生成唯一取件码</summary>/// <param name="cache">redis确保48小时不重复</param>/// <param name="stationCode">站点编码</param>/// <returns></returns>/// <exception cref="ArgumentNullException"></exception>/// <exception cref="Exception"></exception>static string BuildPickupCode(ICache cache, string stationCode){    if (stationCode.IsNullOrEmpty()) throw new ArgumentNullException(nameof(stationCode));
    var rnd = new Random();    for (int i = 0; i < 10; i++)    {        // 生成6位随机数作为取件码,不足6位时前面补0        var code = rnd.Next(100000, 1000000).ToString().PadLeft(6, '0');
        // 站点结合取件码作为唯一key,Redis去重确保48小时内不重复。如果重复再生成一次新的随机数        var key = $"{stationCode}:{code}";        if (cache.Add(key, code, 48 * 3600)) return code;    }
    // 连续10次都失败,就有可能是redis网络或代理有问题了    throw new Exception("Build PickupCode Error!");}

运行效果

.NET快速生成快递柜唯一取件码

原理比较简单,借助Redis的SETNX能力,当key不存在时添加,已存在时不改变已有值。

SETNX的返回值0和1表示是否添加成功。

在NewLife.Redis中redis.Add即是SETNX的封装,如果添加成功,说明这个随机取件码可用,反之则生成新的随机取件码。

Add第二个参数意义不大,第三个参数表示有效期,这里使用48小时。也就是说,这个key在48小时后将会自动消失,该取件码将有可能重新生成用于新的快递。实际运营中,这个有效时间也可能是5到7天。

最后吐槽一下,很多快递柜的8位取件码,实在不利于快速记忆,不利于便捷输入。如果使用6位,大多数人看一次默念一下,即可完成输入!