user-0 提问: 用C语言写一个身份证识别省区！

回复:
user: user-1
content: 这个用C++的容器MAP容器很简单的。可能故意要用C实现吧。还是再好好看下hash的C语言实现吧。感觉你这个好麻烦。 内存现在不缺，用六位的二维数组就能很简单的实现。第一个成员为数字，后面的字符串代表那个省区。直接用省份证的这个值直接索引出来。

user: user-2

user: user-3
content: 为什么不使用stl的map呢？

user: user-4
content: 仅供参考  #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h>  /* ------------------结构体定义------------------ */ typedef struct _hashBucket_t { 	char* key; 	size_t key_len; 	char* data; 	size_t data_len; 	struct _hashBucket_t *next; }  hashBucket_t;  typedef struct _hashMap_t { 	size_t hash_bits; 	size_t bucket_num; 	hashBucket_t bucket[0]; } hashMap_t;  /* -----------------hashmap API ------------------ */ /* count: 预计有多少条数据 */ hashMap_t* hashMapCreate(unsigned long count); void hashMapDestroy(hashMap_t* map); void hashMapInsert(hashMap_t* map, void* key, size_t key_len, void* data, size_t data_len); int hashMapSearch(hashMap_t*   map, void* key, size_t key_len, void** data, size_t* data_len);   /* ------------------demo------------------------ */ int main(void) { 	hashMap_t* map = NULL; 	char* data = NULL; 	size_t data_len = 0; 	int ret;  	map = hashMapCreate(1000);  	hashMapInsert(map, "1+1=", 4, "2", 1); 	hashMapInsert(map, "1+2=", 4, "3", 1); 	hashMapInsert(map, "1+3=", 4, "4", 1); 	hashMapInsert(map, "1+4=", 4, "5", 1); 	hashMapInsert(map, "1+5=", 4, "6", 1); 	hashMapInsert(map, "1+6=", 4, "7", 1); 	hashMapInsert(map, "1+7=", 4, "8", 1); 	hashMapInsert(map, "1+8=", 4, "9", 1); 	hashMapInsert(map, "Hello", -1, "World", -1);  	ret = hashMapSearch(map, "Hello", -1, (void**)&data, &data_len); 	if (ret == 1) { 		printf("%s(len=%zx)\n", data, data_len); 	} 	else { 		printf("not found\n"); 	}  	hashMapDestroy(map);  }  hashMap_t* hashMapCreate(unsigned long count) { 	int i = 0; 	size_t bucket_num = 1; 	size_t hash_bits = 0; 	hashMap_t* map = NULL;  	while (1) { 		bucket_num *= 2; 		hash_bits++; 		if (bucket_num >= count) { 			break; 		} 	} 	 	map = (hashMap_t*)calloc(1, sizeof(hashMap_t) + \ 	sizeof(hashBucket_t) * bucket_num); 	map->bucket_num = bucket_num; 	map->hash_bits = hash_bits;  	return map; }  void hashMapDestroy(hashMap_t* map) { 	int i; 	hashBucket_t* bucket;	 	hashBucket_t* tmp; 	 	for (i = 0; i < map->bucket_num; i++) { 		bucket = &map->bucket[i]; 		if (bucket->key_len == 0) { 			continue; 		} 		free(bucket->data); 		free(bucket->key);  		bucket = bucket->next; 		while (bucket != NULL) { 			free(bucket->data); 			free(bucket->key); 			tmp = bucket; 			bucket = bucket->next; 			free(tmp); 		} 	} 	free(map); }  static unsigned long _calcHashValue(hashMap_t* map, void* key, size_t key_len) { 	char* ch = (char*)key; 	unsigned long seed = 131UL; 	unsigned long hash = 0UL;  	for (ch = (char*)key; ch < (char*)key + key_len; ch++) { 		hash = hash * seed + (*ch); 	}  	hash &= (~0UL >> (sizeof(unsigned long) * 8 - map->hash_bits)); 	 	return hash; }  void hashMapInsert(hashMap_t*      map, void* key, size_t key_len, void* data, size_t data_len) { 	unsigned long hash = _calcHashValue(map, key, key_len); 	hashBucket_t* bucket = &map->bucket[hash];  	if (key_len == -1) { 		key_len = strlen((char*)key); 	} 	if (data_len == -1) { 		data_len = strlen((char*)data); 	}  	if (bucket->key_len) { 		while (bucket->next != NULL) { 			bucket = bucket->next; 		}  		bucket->next = (hashBucket_t*)calloc(1, sizeof(hashBucket_t)); 		bucket = bucket->next; 	}  	bucket->key = (char*)calloc(1, key_len + 1); 	memcpy(bucket->key, key, key_len); 	bucket->key_len = key_len;  	bucket->data = (char*)calloc(1, data_len + 1); 	memcpy(bucket->data, data, data_len); 	bucket->data_len = data_len; }  int hashMapSearch(hashMap_t*   map, void* key, size_t key_len, void** data, size_t* data_len) { 	unsigned long hash = _calcHashValue(map, key, key_len); 	hashBucket_t* bucket = &map->bucket[hash];  	if (key_len == -1) { 		key_len = strlen((char*)key); 	}  	while (bucket != NULL) { 		if ((key_len == bucket->key_len) && !memcmp(key, bucket->key, key_len)) { 			if (data) { 				*data = bucket->data; 			} 			if (data_len) { 				*data_len = bucket->data_len; 			} 			return 1;	 		} 		bucket = bucket->next; 	}  	return 0; }