GCC不返回任何错误或警告。输入密码超过21个字符后,程序会发生段错误。 起初我:接收到SIGSEGV信号:vfprintf.c:没有这样的文件或目录?
hash_p = SuperFastHash(query.pwd, strlen(query.pwd));
从GCC得到这样的警告:
warning: assignment makes pointer from integer without a cast [-Wint- conversion]
hash_p = SuperFastHash(query.pwd, strlen(query.pwd));
^
,所以我把它改为:
sprintf(hash_p, "%d", SuperFastHash(query.pwd, strlen(query.pwd)));
因为哈希函数返回一个int。 strcmp比较两个类型的const char *。
当调试用gdb程序,它返回:
Program received signal SIGSEGV, Segmentation fault.
0xb7e500d5 in _IO_vfprintf_internal (s=<optimized out>, format=<optimized out>,
ap=0xbffff46c "\261\[email protected]") at vfprintf.c:1636
1636 vfprintf.c: No such file or directory.
计划:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdint.h>
#define BUF_SIZE 1024
#undef get16bits
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
#define get16bits(d) (*((const uint16_t *) (d)))
#endif
#if !defined (get16bits)
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
+(uint32_t)(((const uint8_t *)(d))[0]))
#endif
uint32_t SuperFastHash (const char * data, int len) {
uint32_t hash = len, tmp;
int rem;
if (len <= 0 || data == NULL) return 0;
rem = len & 3;
len >>= 2;
for (;len > 0; len--) {
hash += get16bits (data);
tmp = (get16bits (data+2) << 11)^hash;
hash = (hash << 16)^tmp;
data += 2*sizeof (uint16_t);
hash += hash >> 11;
}
switch (rem) {
case 3: hash += get16bits (data);
hash ^= hash << 16;
hash ^= ((signed char)data[sizeof (uint16_t)]) << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits (data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += (signed char)*data;
hash ^= hash << 10;
hash += hash >> 1;
}
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
struct log_n {
char uid[BUF_SIZE];
char pwd[BUF_SIZE];
};
struct log_n acc[1] = {
"username","-1257730142"
};
struct log_n query;
int main() {
char *hash_p;
do {
do{
printf("Username: ");
fgets(query.uid, sizeof query.uid, stdin);
query.uid[strcspn(query.uid, "\n")] = '\0';
if (strlen(query.uid) < 4) {
printf("Username must be between four and eight characters.\nTry again.\n");
}
if (strlen(query.uid) > 8) {
printf("Username must be less than eight characters.\nTry again.\n");
}
} while (strlen(query.uid) < 4 || strlen(query.uid) > 8);
do{
printf("Password: ");
fgets(query.pwd, sizeof query.pwd, stdin);
query.pwd[strcspn(query.pwd, "\n")] = '\0';
sprintf(hash_p, "%d", SuperFastHash(query.pwd, strlen(query.pwd)));
if (strlen(query.pwd) < 21) {
printf("Password must be atleast twenty-one characters long.\nTry again.\n");
}
} while (strlen(query.pwd) < 21);
} while (strcmp(query.uid, acc->uid) !=0 || strcmp(hash_p, acc->pwd) !=0);
}
注:这不是一个家庭作业。我只是在使用互联网的人的帮助下学习C的人。
这可以说这不是一项家庭作业,但值得一提的是我们真的很欢迎这里的作业问题。如果这是作业,它仍然是话题:你有一个明确表示的问题,事先做出明显的努力,人们很乐意在这种情况下提供帮助。我们劝阻的作业问题是没有努力的地方,或者问题作者希望有人帮助他们作弊。 – halfer