如何檢查貨櫃號碼(集裝箱號碼)是否正確?ISO 6346 編碼規則與校驗碼計算教學
在海運與物流系統中,確認貨櫃號碼(Container No.)的正確性非常關鍵。除了直接從資料庫檢索外,最有效率的初步驗證方式就是核對校驗碼(Check Digit)。
本文將詳細解析 ISO 6346 貨櫃編碼規則、校驗碼的數學計算邏輯,並提供完整實用的 C# 範例程式碼。
1. 貨櫃號碼(集裝箱號碼)的編碼規則
根據 ISO 6346 國際標準第 3 部分(Identification system and its associated marks),一個標準貨櫃識別碼由 11 碼 組成,結構如下:
第 1 ~ 3 碼
所有者代碼 (Owner Code)
由 3 個大寫英文字母組成,必須向國際集裝箱局 (BIC, Bureau International des Conteneurs) 註冊,確保全球唯一。
第 4 碼
設備類別 (Equipment Category)
由 1 個拉丁大寫字母組成:
- U:所有貨運貨櫃 (Freight container)
- J:可拆卸貨櫃相關設備 (Attachable equipment)
- Z:拖車和板架 (Trailers and chassis)
第 5 ~ 10 碼
序號 (Serial Number)
由 6 位數字組成。若不足 6 位則前方補 0,由所有者或營運商自行配號。
第 11 碼
校驗碼 (Check Digit)
僅 1 位數字,用於驗證前 10 碼(所有者代碼、設備類別、序號)在輸入或傳輸過程中的正確性。
2. 校驗碼(Check Digit)的計算方法
校驗碼的計算採用「加權模數 11 演算法」,步驟說明如下:
-
A.1 字母對應等效值 (Numerical Equivalents)
將前 10 碼字元轉換為對應數值。數字保持原值(0~9),英文字母(A~Z)則跳過 11 的倍數(如 11, 22, 33)後依序賦予 10 至 38 的數值。 -
A.2 加權因子 (Weighting Factor)
1 到 10 的每個位置都有固定的加權值,分別為 2 的 0 次方到 9 次方(即 20, 21, 22 ... 29):
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512] -
A.3 模數計算 (Modulus 11)
將每一個字元的「等效值 (A.1)」與對應位置的「加權因子 (A.2)」相乘後全部加總,再將總和除以 11 取餘數:
餘數 = ( ∑ (等效值 × 加權因子) ) % 11 -
A.4 確定校驗碼 (Value of Check Digit)
計算出的餘數即為校驗碼。特別注意:若餘數為 10,則校驗碼取為 0。
字母對應等效值表 (A.1 Numerical Equivalents Table)
| 字母 | 對應值 | 字母 | 對應值 | 字母 | 對應值 |
|---|---|---|---|---|---|
| A | 10 | J | 20 | S | 30 |
| B | 12 | K | 21 | T | 31 |
| C | 13 | L | 23 | U | 32 |
| D | 14 | M | 24 | V | 34 |
| E | 15 | N | 25 | W | 35 |
| F | 16 | O | 26 | X | 36 |
| G | 17 | P | 27 | Y | 37 |
| H | 18 | Q | 28 | Z | 38 |
| I | 19 | R | 29 | - | - |
3. 實例計算演練
以貨櫃號碼 TCNU4260450 為例,驗證其第 11 碼校驗碼是否為 0:
| 位置 Index | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 總和 Sum |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 貨櫃字元 | T | C | N | U | 4 | 2 | 6 | 0 | 4 | 5 | - |
| A.1 等效值 | 31 | 13 | 25 | 32 | 4 | 2 | 6 | 0 | 4 | 5 | - |
| A.2 加權因子 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | - |
| 乘積 (A.1 × A.2) | 31 | 26 | 100 | 256 | 64 | 64 | 384 | 0 | 1024 | 2560 | 4509 |
計算結果:
1. 總和加總 = 4509
2. 除以 11 取餘數: 4509 % 11 = 0
3. 取得校驗碼為 0,與貨櫃號碼第 11 碼完全符合!
4. 以程式語言 C# 來取得校驗碼
以下提供經過優化與重構的 C# 函式,能高效且精準地計算出 ISO 6346 貨櫃校驗碼:
ContainerCheckDigit.cs
C#
using System;
using System.Collections.Generic;
public class ContainerValidator
{
/// <summary>
/// 計算並取得貨櫃號碼的校驗碼 (Check Digit)
/// </summary>
/// <param name="containerNo">前 10 碼或完整 11 碼的貨櫃號碼</param>
/// <returns>算出的校驗碼字串,失敗則傳回 null</returns>
public static string GetCheckDigit(string containerNo)
{
if (string.IsNullOrWhiteSpace(containerNo) || containerNo.Length < 10)
return null;
containerNo = containerNo.ToUpper().Trim();
// A.1 字元對應等效值對照表
Dictionary<char, int> charValues = new Dictionary<char, int>()
{
{'A', 10}, {'B', 12}, {'C', 13}, {'D', 14}, {'E', 15},
{'F', 16}, {'G', 17}, {'H', 18}, {'I', 19}, {'J', 20},
{'K', 21}, {'L', 23}, {'M', 24}, {'N', 25}, {'O', 26},
{'P', 27}, {'Q', 28}, {'R', 29}, {'S', 30}, {'T', 31},
{'U', 32}, {'V', 34}, {'W', 35}, {'X', 36}, {'Y', 37},
{'Z', 38}
};
int totalSum = 0;
// 計算前 10 碼的加權總和
for (int i = 0; i < 10; i++)
{
char c = containerNo[i];
int equivalentValue;
if (char.IsLetter(c))
{
if (!charValues.TryGetValue(c, out equivalentValue))
return null; // 無效英文字元
}
else if (char.IsDigit(c))
{
equivalentValue = c - '0';
}
else
{
return null; // 特殊符號無效
}
// 加權因子為 2^i
int weight = (int)Math.Pow(2, i);
totalSum += equivalentValue * weight;
}
// A.3 取 11 模數餘數
int remainder = totalSum % 11;
// A.4 餘數為 10 時轉為 0
int checkDigit = (remainder == 10) ? 0 : remainder;
return checkDigit.ToString();
}
}
沒有留言:
張貼留言