c++ 中的 crypt 返回不同的字符串(或根本没有字符串)
crypt in c++ returning different strings(or no string at all)
我正在尝试创建一个类似于 shadowfile 的 txt 文件,并且我正在使用 crypt 来生成哈希。我通过终端询问密码,然后生成一个伪随机盐。我在 crypt 函数中给出了这两个值,但它每次都创建一个不同的哈希值或根本不创建任何内容,我无法理解我的代码有什么问题。
#include<stdio.h>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<ctime>
#include<crypt.h>
#include<unistd.h>
using namespace std;
/*====== READ STRING DYNAMICALLY ======*/
char* readFromTerminal() {
int length = 0; //counts number of characters
char c; //holds last read character
char *input;
input = (char *) malloc(sizeof (char)); //Allocate initial memory
if (input == NULL) //Fail if allocating of memory not possible
{
printf("Could not allocate memory!");
exit(1);
}
while ((c = getchar()) != '\n') //until end of line
{
realloc(input, (sizeof (char))); //allocate more memory
input[length++] = c; //save entered character
}
input[length] = '[=10=]'; //add terminator
return input;
}
/*====== GENERATE PSEUDO RANDOM SALT VALUE ======*/
char* generateSalt() {
const char alphanum[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; //salt alphanum
int alphanumLength = sizeof (alphanum) - 1; // alphanum lenght
char *salt; //salt string
salt = (char *) malloc(sizeof (char)); //Allocate initial memory
if (salt == NULL) //Fail if allocating of memory not possible
{
printf("Could not allocate memory!");
exit(1);
}
srand(time(NULL));
for (int i = 0; i < 21; i++) {
realloc(salt, (sizeof (char))); //allocate more memory
salt[i] = alphanum[rand() % alphanumLength]; //generate a random character from the alphanum
}
salt[21] = '[=10=]'; //add terminator
return salt;
}
/*====== MAIN ======*/
int main(int argc, char** argv) {
char *username, *password, *salt, *hash;
ofstream myshadow("myshadow.txt", ios::out);
cout << "Enter your username: ";
username = readFromTerminal();
cout << "Enter your password: ";
password = readFromTerminal();
salt = generateSalt();
hash = (char *) malloc(30 * sizeof (char)); //Allocate memory for hash
hash = crypt(password, salt);
myshadow << username << ":" << hash;
return 0;
}
这里有很多需要改进的地方!
- 当 C++ 附带
std::string
时,您使用原始 char *
- 你用显式的
malloc
和realloc
,光是这样就让人觉得问题很快就来了
手动内存管理需要非常谨慎的编程。这里的错误是由于 realloc
的不正确使用引起的:size 参数给出了新的 total 分配的大小,而不是增量。因此,您应该跟踪分配的大小,增加它并使用该新值调用 realloc。由于 realloc
可能 return 一个新的内存块,因此您应该始终使用:
input = (char *) realloc(input, new_size);
顺便说一句,generateSalt
...
中的等效问题
但多亏了 std::getline
,所有这些都已包含在 C++ 中!此外,<random>
模块在旧的 rand
出现大量默认值时带有出色的生成器(rand 与 random 仅 google)
所以代码可以简化为:
include<iostream>
#include<fstream>
#include<unistd.h>
#include <random>
using namespace std;
std::string generateSalt() {
const char alphanum[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; //salt alphanum
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> dis(0, sizeof(alphanum)-1); //Uniform distribution on an interval
char salt[22]; // 21 useful characters in salt (as in original code)
for(char& c: salt) {
c = alphanum[dis(gen)];
}
salt[21] = 0;
return std::string(salt);
}
/*====== MAIN ======*/
int main(int argc, char** argv) {
string username, password, salt, hash;
ofstream myshadow("myshadow.txt", ios::out);
cout << "Enter your username: ";
if (! getline(cin, username)) return 1;
cout << "Enter your password: ";
if (! getline(cin, password)) return 1;
salt = generateSalt();
hash = crypt(password.c_str(), salt.c_str());
myshadow << username << ":" << hash;
return 0;
}
使用 C++ 字符串的另一个好处是分配 和释放 是自动处理的,无需调用 free
...
我正在尝试创建一个类似于 shadowfile 的 txt 文件,并且我正在使用 crypt 来生成哈希。我通过终端询问密码,然后生成一个伪随机盐。我在 crypt 函数中给出了这两个值,但它每次都创建一个不同的哈希值或根本不创建任何内容,我无法理解我的代码有什么问题。
#include<stdio.h>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<ctime>
#include<crypt.h>
#include<unistd.h>
using namespace std;
/*====== READ STRING DYNAMICALLY ======*/
char* readFromTerminal() {
int length = 0; //counts number of characters
char c; //holds last read character
char *input;
input = (char *) malloc(sizeof (char)); //Allocate initial memory
if (input == NULL) //Fail if allocating of memory not possible
{
printf("Could not allocate memory!");
exit(1);
}
while ((c = getchar()) != '\n') //until end of line
{
realloc(input, (sizeof (char))); //allocate more memory
input[length++] = c; //save entered character
}
input[length] = '[=10=]'; //add terminator
return input;
}
/*====== GENERATE PSEUDO RANDOM SALT VALUE ======*/
char* generateSalt() {
const char alphanum[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; //salt alphanum
int alphanumLength = sizeof (alphanum) - 1; // alphanum lenght
char *salt; //salt string
salt = (char *) malloc(sizeof (char)); //Allocate initial memory
if (salt == NULL) //Fail if allocating of memory not possible
{
printf("Could not allocate memory!");
exit(1);
}
srand(time(NULL));
for (int i = 0; i < 21; i++) {
realloc(salt, (sizeof (char))); //allocate more memory
salt[i] = alphanum[rand() % alphanumLength]; //generate a random character from the alphanum
}
salt[21] = '[=10=]'; //add terminator
return salt;
}
/*====== MAIN ======*/
int main(int argc, char** argv) {
char *username, *password, *salt, *hash;
ofstream myshadow("myshadow.txt", ios::out);
cout << "Enter your username: ";
username = readFromTerminal();
cout << "Enter your password: ";
password = readFromTerminal();
salt = generateSalt();
hash = (char *) malloc(30 * sizeof (char)); //Allocate memory for hash
hash = crypt(password, salt);
myshadow << username << ":" << hash;
return 0;
}
这里有很多需要改进的地方!
- 当 C++ 附带
std::string
时,您使用原始 - 你用显式的
malloc
和realloc
,光是这样就让人觉得问题很快就来了
char *
手动内存管理需要非常谨慎的编程。这里的错误是由于 realloc
的不正确使用引起的:size 参数给出了新的 total 分配的大小,而不是增量。因此,您应该跟踪分配的大小,增加它并使用该新值调用 realloc。由于 realloc
可能 return 一个新的内存块,因此您应该始终使用:
input = (char *) realloc(input, new_size);
顺便说一句,generateSalt
...
但多亏了 std::getline
,所有这些都已包含在 C++ 中!此外,<random>
模块在旧的 rand
出现大量默认值时带有出色的生成器(rand 与 random 仅 google)
所以代码可以简化为:
include<iostream>
#include<fstream>
#include<unistd.h>
#include <random>
using namespace std;
std::string generateSalt() {
const char alphanum[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; //salt alphanum
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> dis(0, sizeof(alphanum)-1); //Uniform distribution on an interval
char salt[22]; // 21 useful characters in salt (as in original code)
for(char& c: salt) {
c = alphanum[dis(gen)];
}
salt[21] = 0;
return std::string(salt);
}
/*====== MAIN ======*/
int main(int argc, char** argv) {
string username, password, salt, hash;
ofstream myshadow("myshadow.txt", ios::out);
cout << "Enter your username: ";
if (! getline(cin, username)) return 1;
cout << "Enter your password: ";
if (! getline(cin, password)) return 1;
salt = generateSalt();
hash = crypt(password.c_str(), salt.c_str());
myshadow << username << ":" << hash;
return 0;
}
使用 C++ 字符串的另一个好处是分配 和释放 是自动处理的,无需调用 free
...