許多人習慣在社群媒體分享火車票照片,卻不知火車票上的身份證字號僅以 * 遮蔽出生月日,這看似安全的遮蔽其實存在嚴重資安漏洞。本文透過 C# 程式演示如何從部分遮蔽的身份證號反推完整號碼。
火車票僅遮蔽 4 碼出生月日,理論組合僅 366 種(含閏年),檢查碼 11 種可能,暴力破解極易。
// 權重陣列(前 17 碼)
static int[] weights = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
// 檢查碼對應表
static char[] checkCodes = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
// 驗證身份證號
static bool ValidateID(string id)
{
int sum = 0;
for (int i = 0; i < 17; i++)
sum += int.Parse(id[i].ToString()) * weights[i];
char expected = checkCodes[sum % 11];
return expected == id[17];
}
A123456789****5678)// 核心破解迴圈
DateTime beginDate = new DateTime(year, 1, 1);
int days = DateTime.IsLeapYear(year) ? 366 : 365;
for (int i = 0; i < days; i++)
{
string mmdd = beginDate.AddDays(i).ToString("MMdd");
string candidate = id.Substring(0, 10) + mmdd + id.Substring(14);
if (ValidateID(candidate))
Console.WriteLine($"{GetZodiac(mmdd)} {candidate}");
}
若知道對方星座,可將 30 多組結果對應 12 星座,最終僅剩 2-3 組可能:
static string GetZodiac(int month, int day)
{
string[] signs = { "魔羯座", "水瓶座", "雙魚座", "牡羊座", "金牛座", "雙子座",
"巨蟹座", "獅子座", "處女座", "天秤座", "天蠍座", "射手座" };
int[] boundaries = { 22, 20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22 };
int idx = month - 1;
if (day < boundaries[idx]) idx = (idx - 1 + 12) % 12;
return signs[idx];
}
資安意識從細節開始:一張看似無害的火車票,可能成為身份盜竊的鑰匙。