身份证号码生成(公测).测试BUG
程序代码:main.c 文件
#include
#include
#include
#include
#include
#include
#define DATA struct data
#define AREA struct area
#define INF information //information: 用户信息
AREA * Ap[31]; //定义全局指针数组变量
void sequenceCode(DATA *INF, char identifier[]);
void sexNumber(DATA *INF, char identifier[]);
void label(AREA * head);
AREA * provinceAndCity();
AREA * province();
int verifyCode(char identifier[]);
void anewIdentifier(DATA * INF, char bak[], FILE * fp);
struct data
{
char name[16];
char sex[4];
char birthday[9];
AREA * number;
};
struct area
{
int code;
char address[56];
struct area * next;
};
void openFile(AREA * head, AREA * Ap[])
{
int proving;
FILE * fp;
AREA * p, * q;
p = head;
if ((fp = fopen("areaData.dat", "r")) == NULL)
{
printf("地区数据加载失败,程序退出!");
getch();
exit(-1);
}
while (feof(fp) == 0)
{
if ((q = (AREA *)malloc(sizeof(AREA))) == NULL)
{
printf("内存不足!程序退出!");
getch();
exit(-1);
}
proving = fscanf(fp, "%d %s", &q->code, q->address); //如果正确输入 则返回2
if (proving < 2) //判断是否正确输入
{
free(q); //释放未成功输入信息的空间
q = NULL;
break;
}
label(q);
p->next = q;
p = p->next;
}
fclose(fp);
p->next = NULL;
printf("数据加载成功!\n");
}
int _information(DATA *INF, char identifier[]) //用户信息录入
{
int n;
printf("输入姓名:");
gets(INF->name);
puts("0. 女性");
puts("1. 男性");
printf("选择性别:");
scanf("%d", &n);
switch(n)
{
case 0: strcpy(INF->sex, "女"); break;
case 1: strcpy(INF->sex, "男"); break;
default : printf("输入错误!"); return -1;
}
fflush(stdin); //清空键盘输入流,防前面scanf的回车
printf("输入出生日期:");
gets(INF->birthday);
printf("\n");
puts("0. 直辖市!");
puts("1. 其他省份!");
printf("选择省市:");
scanf("%d", &n);
switch(n)
{
case 0: INF->number = provinceAndCity(); break; //连接直辖市 地址码 并返回该地址码在内存位置地址
case 1: INF->number = province(); break; //连接省份 地址码 并返回该地址码在内存位置地址
default : printf("输入错误!"); return -1;
}
itoa(INF->number->code , identifier, 10); //将整形(int)转换为字符串型存到身份证数组内
strcat(identifier, INF->birthday); //把生日信息连接到身份证数组后
return 0;
}
int saveFile(DATA * INF, char identifier[]) //把屏幕信息保存到文件内
{
FILE * fp;
if ((fp = fopen("saveInformation.txt", "w")) == NULL)
return 1;
fprintf(fp, "性别:%s \n姓名: %s \n出生日期: %s\n身份证号码: %s\n地址:%s \n", INF->sex, INF->name, INF->birthday, identifier, INF->number->address);
fputs("--------------------------------------------------------------------------\n", fp);
fclose(fp);
return 0;
}
int main(void)
{
int r, m;
char n[2]="";
char identifier[19];
char bak[19];
FILE * fp;
AREA head;
DATA INF;
head.next = NULL;
openFile(&head, Ap); //加载地区码
if (_information(&INF, identifier) == -1) //用户信息录入
{
printf("输入异常,程序退出!");
getch();
exit(0);
}
strcpy(bak, identifier); //存储一个备份,等再次生成使用
srand((unsigned)time(NULL)); //让rand()每次随机出来的数不一样的 初始条件
sequenceCode(&INF, identifier); //生成顺序码前两位数
sexNumber(&INF, identifier); //生成性别码
n[0] = verifyCode(identifier); //生成校验码
strcat(identifier, n); //把校验码存到身份证号最后一位
system( "cls "); //清屏!
printf("性别:%s\n", INF.sex);
printf("姓名:%s\n", INF.name);
printf("出生日期:%s\n", INF.birthday);
printf("身份证号码:%s\n", identifier);
printf("地址:%s\n", INF.number->address);
r = saveFile(&INF, identifier); //把屏幕信息保存到文件内
if (r == 0)
printf("以上信息以成功保存到saveInformation.txt内!\n");
else
system("del saveInformation.txt");
if ((fp = fopen("saveInformation.txt", "a")) == NULL) //以最加形式打开文件
return 0;
while(1)
{
printf("输入'0'再次生成编号!");
if(getch() == '0')
anewIdentifier(&INF, bak, fp);
else
break;
}
fclose(fp);
//province();
//for(i=0; i<31; i++)
// printf("%s %s\n", Ap[i]->code, Ap[i]->address);
//provinceAndCity();
return 0;
}chooseArea.c 文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define DATA struct data
#define AREA struct area
extern AREA * Ap[31];
extern struct area //声明area 已经在其他源文件中已经声明
{
int code;
char address[56];
struct area * next;
};
extern struct data //同上
{
char name[16];
char sex[4];
char birthday[9];
AREA * number;
};
void label(AREA * head) //记录第一个直辖市 或 省份 的地址
{
AREA * p;
static int i=0;
p = head;
if (p->code % 10000 == 0)
{
Ap[i] = p;
//printf("%d.\t%s\n", i, Ap[i]->address);
i++;
}
}
void sequenceCode(DATA *INF, char identifier[]) //生成顺序码前两位数
{
int i;
char temp[4];
//srand((unsigned)time(NULL));
i = rand() % 100; //随机出一个数
itoa(i, temp, 10); //转换成字符串储存在temp数组内
if (i <= 9)
{
strcat(identifier, "0"); //如果随机出现的数小于9,在身份证数组内连接一个字符0
strcat(identifier, temp); //连接随机数
}
else
strcat(identifier, temp);
}
void sexNumber(DATA *INF, char identifier[]) //生成性别码
{
int i;
char temp[4];
//srand((unsigned)time(NULL));
i = rand() % 10;
if (strcmp(INF->sex, "女") == 0)
{
while(i % 2 != 0) //让随机函数随机出一个偶数
i = rand() % 10;
itoa(i, temp, 10);
strcat(identifier, temp);
}
else if(strcmp(INF->sex, "男") == 0)
{
while(i % 2 == 0) //让随机函数随机出一个奇数
i = rand() % 10;
itoa(i, temp, 10);
strcat(identifier, temp);
}
}
AREA * provinceAndCity()
{
int j, n, m;
AREA * p, * temp[50];
printf("0.\t%s\n", Ap[0]->address);
printf("1.\t%s\n", Ap[1]->address);
printf("2.\t%s\n", Ap[8]->address);
printf("3.\t%s\n", Ap[21]->address);
printf("输入你城市编号:");
scanf("%d", &n);
switch(n)
{
case 0: m = 0; break;
case 1: m = 1; break;
case 2: m = 8; break;
case 3: m = 21; break;
}
p = Ap[m];
j = 0;
while (p->code != Ap[m+1]->code)
{
printf("%d.\t%s\n", j, p->address); //输出该阶段的的区县
temp[j] = p; //并把该段区县地址存的内存地址存到temp指针数组内
j++;
p = p->next;
}
printf("输入你区县编号:");
scanf("%d", &n);
printf("%s\n", temp[n]->address);
return temp[n];
}
AREA * province()
{
int i, j, n, m;
AREA * p, * temp[60], * temp_2[30];
for(i=2; i<8; i++)
printf("%d.\t%s\n", i-2, Ap[i]->address);
for(i=9; i<21; i++)
printf("%d.\t%s\n", i-3, Ap[i]->address);
for(i=22; i<31; i++)
printf("%d.\t%s\n", i-4, Ap[i]->address);
printf("输入你省份编号:");
scanf("%d", &n);
if (n < 8)
n += 2;
else if (n < 21)
n += 3;
else
n += 4;
p = Ap[n];
j = 0;
while (p != Ap[n+1])
{
if (p->code % 100 == 0)
{
printf("%d.\t%s\n", j, p->address);
temp[j] = p;
j++;
}
p = p->next;
}
printf("输入你城市编号:");
scanf("%d", &m);
p = temp[m];
j = 0;
while (p!= temp[m+1] && p!= Ap[n+1])
{
printf("%d.\t%s\n", j, p->address);
temp_2[j] = p;
j++;
p = p->next;
}
printf("输入你区县编号:");
scanf("%d", &n);
printf("%s\n", temp_2[n]->address);
return temp_2[n];
}
int verifyCode(char identifier[])
{
int i, n, m, y[17],sum=0;
int t[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
char temp[19];
strcpy(temp, identifier);
for (i=0; temp[i] != '\0'; i++) //把字符型的数字-'0'=就等于该数字字符的阿拉伯数字
y[i] = temp[i] - '0';
for (i=0; temp[i] != '\0'; i++) //将身份证号码前17位数分别乘以不同的系数,系数即是数组t[18]
t[i] *= y[i];
for (i=0; temp[i] != '\0'; i++) //将得到的17个乘积相加。
sum += t[i];
n = sum % 11; //将相加后的和除以11并得到余数
switch(n) //余数可能为0 1 2 3 4 5 6 7 8 9 10这些个数字,其对应的身份证最后一位校验码为1 0 X 9 8 7 6 5 4 3 2。
{
case 0: m = 1; break;
case 1: m = 0; break;
case 2: m = 72; break;
case 3: m = 9; break;
case 4: m = 8; break;
case 5: m = 7; break;
case 6: m = 6; break;
case 7: m = 5; break;
case 8: m = 4; break;
case 9: m = 3; break;
case 10: m = 2; break;
}
return m+'0'; //还原回字符
}
void anewIdentifier(DATA * INF, char bak[], FILE * fp)
{
char temp[19];
char n[2]="";
strcpy(temp, bak);
sequenceCode(INF, temp);
sexNumber(INF, temp); //生成性别码
n[0] = verifyCode(temp); //生成校验码
strcat(temp, n); //把校验码存到身份证号最后一位
printf("身份证号码:%s\n", temp);
fputs(temp, fp);
fputs("\n", fp);
fflush(fp);
return;
}这个工程由两个文件组成..
分别保存为main.c和chooseArea.c
用vc++6.0 添加这两个文件即可使用;;
望发现BUG把发到hz453@内.






