首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 結合時間戳與密碼級隨機字串產生唯一訂單編號

     編輯:關於C語言

電商、金流、物流系統常需產生「唯一、不可預測、可排序」的訂單編號。單純用 DateTime.Now.Ticks 或 Guid.NewGuid() 皆有缺失:前者並發下易衝突,後者無序且過長。本文示範「時間戳(精確到秒/毫秒)+ 密碼級隨機字串」的組合策略,兼顧唯一性、可讀性與安全性。

核心設計

  1. 時間前綴:yyyyMMddHHmmss(或 yyyyMMddHHmmssfff 含毫秒),天然可排序、人類可讀。
  2. 隨機尾碼:使用 RNGCryptoServiceProvider(或 .NET 6+ RandomNumberGenerator)產生 5~8 碼英數字元,確保同秒內大量並發不重複。
  3. 總長度可控:14+8=22 碼,適合資料庫索引與人工閱讀。

完整實作(.NET Framework / .NET Core 通用)

using System;
using System.Security.Cryptography;
using System.Text;

public static class OrderNoGenerator
{
    private const string Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create(); // .NET Core 3.0+

    /// 
    /// 產生指定長度的密碼級隨機字串
    /// 
    public static string GetRandomSuffix(int length = 8)
    {
        if (length < 1) throw new ArgumentOutOfRangeException(nameof(length));
        var bytes = new byte[length];
        Rng.GetBytes(bytes);
        var sb = new StringBuilder(length);
        foreach (byte b in bytes)
            sb.Append(Chars[b % Chars.Length]);
        return sb.ToString();
    }

    /// 
    /// 產生唯一訂單編號:yyyyMMddHHmmss + 隨機尾碼
    /// 
    public static string Generate(bool includeMilliseconds = false, int suffixLength = 8)
    {
        string timePart = DateTime.Now.ToString(includeMilliseconds ? "yyyyMMddHHmmssfff" : "yyyyMMddHHmmss");
        return timePart + GetRandomSuffix(suffixLength);
    }
}

使用範例

for (int i = 0; i < 10; i++)
{
    // 含毫秒 + 8 碼隨機
    Console.WriteLine(OrderNoGenerator.Generate(true, 8));
    // 無毫秒 + 6 碼隨機(較短)
    Console.WriteLine(OrderNoGenerator.Generate(false, 6));
}

輸出樣本

20240518143022123Xk9pQ2z
20240518143022aB3f
20240518143022456Yz8mN1q
20240518143022dE7h
...

關鍵細節與替代方案

方案優點缺點適用場景
時間戳 + RNGCryptoServiceProvider可排序、不可預測、長度固定極高併發(萬級/秒)理論仍有極微機率衝突一般電商訂單、物流單號
時間戳(毫秒) + Interlocked.Increment 計數器同進程內絕對不重複、效能極高跨進程/分散式部署需額外協調單體高併發服務
Snowflake 演算法 (64-bit Long)分散式唯一、趨勢遞增、數值型索引極快需部署機器 ID、時鐘回撥處理微服務、分散式系統主鍵
Guid.NewGuid().ToString("N")無需協調、標準庫支援32 碼、無序、索引碎片化嚴重非索引欄位、臨時 Token

資料庫索引建議

  • 訂單編號欄位建立 叢集索引(Clustered Index)或 主鍵,時間前綴在前可維持插入順序,減少頁分裂。
  • 若使用 Snowflake ID,請用 BIGINT 儲存,避免字串比較開銷。

遷移到 .NET 6+ 的現代化寫法

// RandomNumberGenerator 為靜態單例,執行緒安全
private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();

public static string GetRandomSuffix(int length)
{
    Span<byte> bytes = stackalloc byte[length];
    _rng.GetBytes(bytes);
    return string.Create(length, bytes, (chars, b) => {
        for (int i = 0; i < length; i++)
            chars[i] = Chars[b[i] % Chars.Length];
    });
}

採用「時間戳 + 密碼級隨機」策略,即能以極低複雜度產出兼具業務可讀性與技術唯一性的訂單編號,滿足絕大多數中小型系統需求;若進入分散式高併發領域,再引入 Snowflake 或 ULID 等演算法即可平滑升級。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved