shell加密程序如何使用较少的用户时间?

时间:2009-04-26 08:18:32

标签: c profiling

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);
}

2 个答案:

答案 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)

我怀疑这基本上表明加密不是这个特定脚本性能的重要部分。

但是,让文件系统第一次加载目录的内容很重要。加载后,它可能会被缓存。这可以解释为什么第一次运行两者时,无论哪一个先执行都会慢一些。之后,他们可能会非常相似,使用文件系统缓存。

如果你重新启动(以确保你正在清除缓存)并反过来运行它,我希望加密版本需要更长的时间,因为它将转到磁盘而不是缓存