#include
#include
#include
#define ERROR_YEAR 0x0100
#define ERROR_MONTH 0x0200
#define ERROR_DAY 0x0400
#define ERROR_LENGTH 0x0800
#define ERROR_CHECK 0x1000
int isLeapYear(int year)
{
if ((year % 400) == 0) return 1;
if ((year % 100) == 0) return 0;
if ((year % 4) == 0) return 1;
return 0;
}
int checkDay(int year, int month, int day)
{
if (month < 1 || month > 12) return ERROR_MONTH;
const int monthday[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(day < 1) return ERROR_DAY;
if(day > monthday[month] + ((month == 2) ? isLeapYear(year) : 0)) return ERROR_DAY;
return 0;
}
int checkID(const char * id)
{
// 取得当前年份
time_t timer = time(NULL);
tm * ptm = localtime(&timer);
int curYear = ptm->tm_year + 1900;
// 验证身份证都是数字
const char * pid = id;
while(*pid && isdigit(*pid)) pid++;
size_t len = pid - id; // 通过验证的长度
// 行政区划验证比较复杂,略
if(len == 15) // 15为身份证
{
int year = id[6] * 10 + id[7] - 528;
int month = id[8] * 10 + id[9] - 528;
int day = id[10] * 10 + id[11] - 528;
if((curYear % 100) < year) year += 2000;
else year += 1900;
return checkDay(year, month, day) | 15;
}
if(len == 17)
{
if(id[17] != 'x' && id[17] != 'X') return ERROR_LENGTH;
len = 18;
}
if(len == 18)
{
int year = id[6] * 1000 + id[7] * 100 + id[8] * 10 + id[9] - 53328;
int month = id[10] * 10 + id[11] - 528;
int day = id[12] * 10 + id[13] - 528;
int ret = checkDay(year, month, day);
if(ret) return ret;
int weight[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; // 十七位数字本体码权重
char validate[] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; // mod11, 对应校验码字符值
int sum = 0;
for(int i = 0; i < 17; ++i) sum += weight[i] * (id[i] - '0');
if(validate[sum % 11] != id[17]) return ERROR_CHECK;
return 18;
}
return ERROR_LENGTH;
}
void printResult(int x)
{
if(x & ERROR_YEAR) printf("年输入错误 ");
if(x & ERROR_MONTH) printf("月输入错误 ");
if(x & ERROR_DAY) printf("月输入错误 ");
if(x & ERROR_LENGTH) printf("输入长度错误 ");
if(x & ERROR_CHECK) printf("校验错误 ");
if(x & 0xFF00) printf("\n");
else printf("%d位号码输入正确\n", x & 0xFF);
}
int main()
{
char buf[32];
while(1)
{
scanf("%s", buf);
printResult(checkID(buf));
}
return 0;
}