using Microsoft.Extensions.Logging; namespace StopShopping.Services.Implementions; public class SerialNoGenerator : ISerialNoGenerator { public SerialNoGenerator(ILogger logger) { _logger = logger; } private readonly ILogger _logger; private const long START_UTC = 1767196800000; //2026-01-01 00:00:00.000 private const int BITS_CALLBACK = 3; private const int BITS_SERIAL = 6; private const long MASK_CALLBACK = ~(-1L << BITS_CALLBACK); //0b_0111 private const long MASK_SERIAL = ~(-1L << BITS_SERIAL); private readonly object _lockObj = new(); private long _lastUtc = DateTimeOffset.Now.ToUnixTimeMilliseconds(); private long _serial; private long _callbackSerial; /// /// /// /// /// 0000000 /// /// /// 00000000000 /// /// /// 00000000000 /// /// /// 0000000000 /// /// /// /// /// /// 符号位1bit /// /// /// /// 毫秒时间戳56bit /// /// /// 时间回拨标识3bit /// /// /// 毫秒内序号6bit /// /// /// /// public string GenerateRequestNo() { lock (_lockObj) { var currUtc = DateTimeOffset.Now.ToUnixTimeMilliseconds(); if (currUtc < _lastUtc) //时间回拨 { currUtc = _lastUtc; _callbackSerial = (_callbackSerial + 1) & MASK_CALLBACK; if (_callbackSerial == 0) //时间回拨标识数据段用完 { _logger.LogWarning("服务器时间不准,序列号可能重复,请检查!"); } } if (currUtc > _lastUtc) { _serial = 1; _callbackSerial = 0; } else { _serial = (_serial + 1) & MASK_SERIAL; if (_serial == 0) //毫秒内数据段用完 { WaitNextMilliSecond(ref currUtc); _serial = 1; } } _lastUtc = currUtc; long serial = ((currUtc - START_UTC) << BITS_CALLBACK + BITS_SERIAL) | (_callbackSerial << BITS_SERIAL) | _serial; return string.Format("R{0}", serial); } } public string GenerateProductNo() { throw new NotImplementedException(); } private void WaitNextMilliSecond(ref long curr) { while (_lastUtc >= curr) { curr = DateTimeOffset.Now.ToUnixTimeMilliseconds(); } } public string GenerateRandomPassword() { throw new NotImplementedException(); } }