Linux 上目录中的文件加密问题
我已经测试了程序的加密部分,它对于单个文件甚至“文件1,文件2,文件3”之类的文件都可以正常工作,但它不适用于目录。该代码对我来说看起来不错,但是在执行时它给了我一个分段错误。
它应该加密目录中的文件,并使用新扩展名(旧名称+“.wbf”)将它们写入同一目录中,并通过相反的扩展名删除进行解密。我只会发布处理文件的代码部分,处理单个文件的 do_crypt 函数工作得很好,我认为这不是我的问题的根源。
// PHP explode function
vector<string> explode (string text, char separator)
{
vector<string> split;
int last_trip = 0, pos = 0;
text += separator;
for (pos = 0; pos < text.size(); pos++)
{
if (text[pos] != separator)
{
// continue with iteration
}
else
{
split.push_back(text.substr(last_trip, pos - last_trip));
last_trip = pos + 1;
}
}
return split;
};
// LINUX -- directory listing function
string LS (string dir)
{
DIR *dp;
vector<string> files;
struct dirent *dirp;
if ((dp = opendir(dir.c_str())) = NULL)
{
cout << "Error (" << errno << ") opening " << dir << endl;
//return errno;
}
while ((dirp = readdir(dp)) != NULL)
{
files.push_back(string(dirp->d_name));
}
closedir(dp);
string explosive = "";
for (int i = 0; i < files.size(); i++)
{
explosive += files[i];
if (i != (files.size() - 1)) { explosive += ','; }
}
return 0;
}
// various functions for encryption
int main (int argc, char* argv[])
{
cout << "\t! ENCRYPTR -- File encryption utility written by WBlinder, 2010. !" << endl << endl;
cout << "\t\t\t\tOPTIONS:" << endl;
cout << "\t\t\t1\tCRYPT A FILE" << endl << "\t\t\t2\tDECRYPT A FILE" << endl << endl;
cout << "choice > ";
int opt;
cin >> opt;
string sin, sout;
string dummy; getline(cin, dummy);
/*cout << "input files > ";
cout.clear(); cin.clear();
getline(cin, sin);
vector<string> fin = explode(sin, ',');
cout << "output files > ";
getline(cin, sout);
vector <string> fout = explode(sout, ',');
if (sin.size() != sout.size())
{
cout << "NO. INPUT FILES UNEQUAL NO. OUTPUT FILES" << endl;
return 1;
}*/
string dir;
cout << "dir > ";
getline (cin, dir);
vector<string> input = explode(dir, ',');
vector<string> output = input;
switch (opt)
{
case 1:
for (int i = 0; i < output.size(); i++)
{
output[i] = output[i] + ".wbf";
}
break;
case 2:
for (int i = 0; i < output.size(); i++)
{
output[i] = output[i].substr(0, (output[i].size() - 4));
}
break;
}
cout << "password > ";
getline(cin, key);
cout << "N > ";
cin >> N;
cout << "(768 => fairly secure\t3072 => secure)\nextra rounds > ";
cin >> drop;
for (int brick = 0; brick < input.size(); brick++)
{
do_crypt(opt, dir + input[brick], dir + output[brick]);
}
/*string text;
cout << "text to split: ";
getline (cin, text);
vector<string> tnt = explode(text, '.');
for (int i = 0; i < tnt.size(); i++)
{
cout << i << ": " << tnt[i] << endl;
}*/
}
I have tested the encryption part of the program and it works just fine for individual files, or even things like "file1,file2,file3" but it doesn't work with directories. The code looks fine to me, however when executing it gives me a segmentation fault.
It's supposed to encrypt files in directory and write them in the same directory with a new extension (old name + ".wbf") and decryption with extension removal upon the opposite. I'm only going to post the parts of code that deal with the files, the do_crypt function that works with individual files works just fine, and I think it's not the source of my problems.
// PHP explode function
vector<string> explode (string text, char separator)
{
vector<string> split;
int last_trip = 0, pos = 0;
text += separator;
for (pos = 0; pos < text.size(); pos++)
{
if (text[pos] != separator)
{
// continue with iteration
}
else
{
split.push_back(text.substr(last_trip, pos - last_trip));
last_trip = pos + 1;
}
}
return split;
};
// LINUX -- directory listing function
string LS (string dir)
{
DIR *dp;
vector<string> files;
struct dirent *dirp;
if ((dp = opendir(dir.c_str())) = NULL)
{
cout << "Error (" << errno << ") opening " << dir << endl;
//return errno;
}
while ((dirp = readdir(dp)) != NULL)
{
files.push_back(string(dirp->d_name));
}
closedir(dp);
string explosive = "";
for (int i = 0; i < files.size(); i++)
{
explosive += files[i];
if (i != (files.size() - 1)) { explosive += ','; }
}
return 0;
}
// various functions for encryption
int main (int argc, char* argv[])
{
cout << "\t! ENCRYPTR -- File encryption utility written by WBlinder, 2010. !" << endl << endl;
cout << "\t\t\t\tOPTIONS:" << endl;
cout << "\t\t\t1\tCRYPT A FILE" << endl << "\t\t\t2\tDECRYPT A FILE" << endl << endl;
cout << "choice > ";
int opt;
cin >> opt;
string sin, sout;
string dummy; getline(cin, dummy);
/*cout << "input files > ";
cout.clear(); cin.clear();
getline(cin, sin);
vector<string> fin = explode(sin, ',');
cout << "output files > ";
getline(cin, sout);
vector <string> fout = explode(sout, ',');
if (sin.size() != sout.size())
{
cout << "NO. INPUT FILES UNEQUAL NO. OUTPUT FILES" << endl;
return 1;
}*/
string dir;
cout << "dir > ";
getline (cin, dir);
vector<string> input = explode(dir, ',');
vector<string> output = input;
switch (opt)
{
case 1:
for (int i = 0; i < output.size(); i++)
{
output[i] = output[i] + ".wbf";
}
break;
case 2:
for (int i = 0; i < output.size(); i++)
{
output[i] = output[i].substr(0, (output[i].size() - 4));
}
break;
}
cout << "password > ";
getline(cin, key);
cout << "N > ";
cin >> N;
cout << "(768 => fairly secure\t3072 => secure)\nextra rounds > ";
cin >> drop;
for (int brick = 0; brick < input.size(); brick++)
{
do_crypt(opt, dir + input[brick], dir + output[brick]);
}
/*string text;
cout << "text to split: ";
getline (cin, text);
vector<string> tnt = explode(text, '.');
for (int i = 0; i < tnt.size(); i++)
{
cout << i << ": " << tnt[i] << endl;
}*/
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的 LS 函数存在很多问题。首先,您应该让它直接返回一个
vector
,而不是使用逗号分隔值将数据打包在string
中。这将节省您对explode
函数的调用,并且如果目录包含带逗号的文件名(这是 Linux 上的有效名称),也不会中断。但更大的问题(导致)您的段错误是
return 0
行。由于您的函数被声明为返回一个string
对象,并且由于string
类具有来自const char*
的隐式构造函数,因此它由编译器返回字符串(NULL)
。当使用NULL
指针调用时,此构造函数会引发logic_error
异常。由于您没有捕获异常,C++ 运行时会调用abort
函数。此函数在设计上会导致段错误,以便停止执行(如果启用,则会生成核心转储以允许事后调试)。您至少应该像这样重写您的
LS
函数:或者更好的是,更改其签名以返回
vector
并像这样重写它:There is many problem in your
LS
function. First, you should make it directly return avector<string>
instead of packing the data in astring
using a comma to separate value. This would save you a call toexplode
function, and would not break if the directory contains a filename with a comma in it (which is a valid name on Linux).But the bigger problem (that is causing) your segfault is the
return 0
line. Since your function is declared to return astring
object, and sincestring
class has an implicit constructor fromconst char*
, this is interpreted by the compiler asreturn string(NULL)
. And when called with aNULL
pointer this constructor raise alogic_error
exception. As you didn't catch the exception, the C++ runtime call theabort
function. This function cause a segfault by design in order to stop execution (and if enabled generate a coredump to allow post-morten debugging).You should at least rewritte your
LS
function like that:Or better, change its signature to return a
vector<string>
and rewrite it like that:if ((dp = opendir(dir.c_str())) = NULL)
我认为你的意思是
== NULL
if ((dp = opendir(dir.c_str())) = NULL)
I think you mean
== NULL