UPDATE2:
移植到autotools并上传到SourceForge。
更新:
我将对此进行一些更严格的测试,但我认为该问题与缓存和两个测试用例的排序有关可能很重要。另外我知道加密是可悲的,在两个文件中重复,并且代码低于初稿质量。我也知道我应该使用makefile等。我不建议在任何地方使用它。我把它一起搅打并简化下来,以便从其他人那里得到最好的输入。
原始问题:
我完全难过了。我创建了一个基于此previous question来加密shell脚本的包装器,它运行良好;但是,在确定性能问题时,加密脚本占用的时间更少!你能帮我解释一下吗?我只是不明白。我已经将所有内容都删除了基础,并尽可能地简化了它。如果你拿起我的文件,你必须拥有文件/ usr / bin / shelldecrypt的写权限。
ojblass@XXXXX:~/source/shellcrypt>./build ojblass@XXXXX:~/source/shellcrypt>./run example.sh.bin is encrypted run it to view output ojblass@XXXXX:~/source/shellcrypt>./profile example.sh real 0m0.107s user 0m0.048s sys 0m0.052s example.sh.bin real 0m0.118s user 0m0.036s sys 0m0.068s ojblass@XXXXX:~/source/shellcrypt>
[构建]
gcc shellencrypt.c mv a.out shellencrypt gcc shelldecrypt.c mv a.out shelldecrypt cp shelldecrypt /usr/bin
[example.sh]
#!/bin/bash ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null ls -lt >> /dev/null
[资料]
echo example.sh time example.sh echo example.sh.bin time example.sh.bin
[运行]
rm -rf example.sh.bin ./shellencrypt example.sh chmod 755 example.sh.bin echo example.sh.bin is encrypted run it to view output
[shelldecrypt.c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
/* #define DEBUG */
static int flip( int a)
{
int b;
b = a;
b ^= 0x000C;
return b;
}
static void trace ( char * szMessage )
{
#ifdef DEBUG
if (szMessage != NULL)
{
printf("DEBUG Message %s\n",szMessage);
}
#endif
return;
}
int main(int argc, char *argv[]) {
FILE *fp = NULL;
int ch=(char) 0;
int foundnl=0;
char shellpath[4096]; /* what happened to PATH_MAX? */
char *ptest;
FILE *pipe = NULL;
/* TODO REMOVE memset(bangline, 0, sizeof(bangline)); */
trace("STARTING");
trace(argv[0]);
trace("ARGUMENT");
/* get the shell environment variable */
ptest = getenv("SHELL");
if (ptest == NULL)
{
trace("could not get shell environment variable");
return (EXIT_FAILURE);
}
else
{
strcpy(shellpath, getenv("SHELL"));
trace(shellpath);
}
if ((argc >=1) && (argv[1]!=NULL))
{
trace(argv[1]);
}
else
{
trace("(null)");
}
if (argc == 2) {
fp = fopen(argv[1],"r");
if (fp == NULL) {
fprintf(stderr,"Unable to open file %s. Exiting.\n",argv[1]);
exit(EXIT_FAILURE);
}
}
else
{
printf("Usage: %s <filename>\n",argv[0]);
exit (EXIT_SUCCESS);
}
/* strip out the bangline which is not encryped */
while ((ch = fgetc(fp)) != EOF) {
if (ch == 10)
{
foundnl = 1;
break;
}
}
if (foundnl!=1)
{
(void) fclose(fp);
trace("FOUND NO NEWLINE BEFORE END OF FIRST LINE");
return (EXIT_SUCCESS);
}
pipe = popen(shellpath, "w");
if (pipe == NULL)
{
trace("popen failed");
(void) fclose(fp);
return (EXIT_FAILURE);
}
else
{
trace("writing string to pipe");
while ((ch = fgetc(fp)) != EOF) {
(void) fputc(flip(ch),pipe);
}
/* (void) fputc(EOF,pipe); */
}
if (pipe != NULL)
(void) pclose(pipe);
if (fp != NULL)
(void) fclose(fp);
exit (EXIT_SUCCESS);
}
[shellencrypt.c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int flip( int a)
{
int b;
b = a;
b ^= 0x000C;
return b;
}
int main(int argc, char *argv[]) {
FILE *fp = NULL, *fpOut=NULL;
int ch;
char szOutputFileName[2000];
strcpy(szOutputFileName,"");
if (argc == 2) {
fp = fopen(argv[1],"r");
if (fp == NULL) {
fprintf(stderr,"Unable to open file %s. Exiting.\n",argv[1]);
exit(EXIT_FAILURE);
}
}
else
{
printf("Usage: %s <filename>\n",argv[0]);
exit (EXIT_SUCCESS);
}
strcpy(szOutputFileName, argv[1]);
strcat(szOutputFileName, ".bin");
fpOut = fopen(szOutputFileName,"wt");
if (fpOut == NULL)
{
fprintf(stderr,"Unable to open file %s. Exiting.\n",szOutputFileName);
if (fp)
(void) fclose(fp);
exit(EXIT_FAILURE);
}
/* print the header */
fprintf(fpOut,"#!/usr/bin/shelldecrypt\n");
/* read until the end of file, encrypting characters and writing them out to target file */
while ((ch = fgetc(fp)) != EOF) {
(void) fputc(flip(ch),fpOut);
}
if (fp)
(void) fclose(fp);
if (fpOut)
(void) fclose(fpOut);
return(EXIT_SUCCESS);
}
答案 0 :(得分:4)
这并不是一个足够大的差异,我认为这会产生任何影响。更好的“概况”是:
#!/bin/bash
echo example.sh
/usr/bin/time sh -c 'for i in $(seq 1 1000); do ./example.sh; done'
echo example.sh.bin
/usr/bin/time sh -c 'for i in $(seq 1 1000); do ./example.sh.bin; done'
在我的机器上,我得到了:
example.sh
39.46user 33.22system 1:16.92elapsed 94%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+8547221minor)pagefaults 0swaps
example.sh.bin
42.33user 42.13system 1:33.98elapsed 89%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+9376313minor)pagefaults 0swaps
这还不足以显示明确地“加密”的那个更慢(尽管我显然认为它是),但它肯定表明加密的不会在简单的基准测试中始终减少用户时间。
此外,您的代码还存在其他一些严重问题。最明显的是,这并不接近声音加密。正如其他人所说,你正在接近这个问题。您在“几小时内”提出的加密算法并不能代替声音权限。
此外,您需要使用makefile而不是增加不必要的shell脚本。学习基本的gcc选项,比如-o。除非用户运行安装目标(在这种情况下/ usr / local / bin仍然会更好),否则不要尝试复制到/ usr / bin /。
答案 1 :(得分:2)
我怀疑这基本上表明加密不是这个特定脚本性能的重要部分。
但是,让文件系统第一次加载目录的内容很重要。加载后,它可能会被缓存。这可以解释为什么第一次运行两者时,无论哪一个先执行都会慢一些。之后,他们可能会非常相似,使用文件系统缓存。
如果你重新启动(以确保你正在清除缓存)并反过来运行它,我希望加密版本需要更长的时间,因为它将转到磁盘而不是缓存