EMS和顺丰一样,单号是不连的,这样在开发快递单方面的软件时,想自动算出下一个号还真麻烦。找了下网上的,好像没人公布这些算法呀。
public static string getNextExpId(string oId) { string str1 = ""; // 先判断是否ems if (myMatch(oId, "E[ -Z 9}C[A-Z]+$", 0) != "") // 注意:原文条件判断可能有误,这里按逻辑修正 { string s_oNum = userHelper.myMatch(oId, "\\d+", 0); // 获取旧的id数字部分 long tmp_Num = long.Parse(s_oNum.Substring(0, 8)) + 1; str1 = oId.Replace(s_oNum, tmp_Num.ToString()); // 新ems号 // 计算校验码 long num_1 = 8 * long.Parse(str1.Substring(2, 1)); long num_2 = 6 * long.Parse(str1.Substring(3, 1)); // 注意:原文代码缺失此行,根据EMS算法补充 long num_4 = 2 * long.Parse(str1.Substring(5, 1)); long num_5 = 3 * long.Parse(str1.Substring(6, 1)); long num_6 = 5 * long.Parse(str1.Substring(7, 1)); long num_7 = 9 * long.Parse(str1.Substring(8, 1)); long num_8 = 7 * long.Parse(str1.Substring(9, 1)); long num_sum = num_1 + num_2 + num_4 + num_5 + num_6 + num_7 + num_8; long num_mod = num_sum % 11; long num_result = 11 - num_mod; if (num_result == 11) { num_result = 0; // 校验码为0 } else if (num_result == 10) { num_result = 5; // 校验码为5 } return str1.Insert(3, num_result.ToString()); } // 普通单号处理 str1 = userHelper.myMatch(oId, "\\d+", 0); // 取数字部分 return oId.Replace(str1, (long.Parse(str1) + 1).ToString()); }
注意:原文代码中存在一些问题: 1. 正则表达式判断条件可能有误 2. 缺少num_2的计算(应为第4位数字乘以6) 3. 校验码为11时应为0,为10时应为5(原文描述可能有误)
格式:EMS单号通常以"E"开头,后跟13位数字
校验位:第4位为校验码,通过特定算法计算得出
计算方法:前11位数字按特定权重相乘后求和,对11取模,再用11减去余数得到校验码
权重:第2-3位权重为8、6,第5-11位权重依次为4、2、3、5、9、7
特殊规则:校验码计算结果为10时用5代替,为11时用0代替
应用价值:该算法可用于快递管理系统中自动生成下一个EMS单号,避免手动输入错误,提高工作效率。对于开发快递单打印、跟踪等软件具有重要参考价值。