2015-04-02 7 views
0

Я работаю над назначением для создания оболочки в C. Программа должна прочитать файл конфигурации, в котором перечислены команды, разрешенные в оболочке. Также в этом файле конфигурации для каждой разрешенной команды также указывается значение контрольной суммы sha1. Проба строка будет выглядеть следующим образом: (файл имеет другие данные тоже)Сравнение значений контрольной суммы SHA в C

... other data .... 
* /bin/ls 3848bdeada63dc59d2117a6ca1348fe0981ad2fc 

Когда пользователь вводит команду, программа должна проверить, что команда находится в файле конфигурации или нет. Если команда находилась в списке, программа должна получить значение sha1 sha1, а затем вычислить значение суммы sha1 для данного файла и сравнить их.

У меня проблема со сравнением этих значений. Я прочитал значение sha1 из файла и сохранил его в указателе char *. Позже я использую SHA1() для вычисления значения контрольной суммы. Но значение, возвращаемое SHA1, является неподписанным указателем char *. И я не могу понять, как сравнивать эти значения.

Итак, мой вопрос: следует ли изменить, как я читаю данные? (Учитывая, что в этом файле есть другие данные). Как сравнить эти два значения контрольной суммы?

(Я отправил еще один вопрос here, который был частью этой проблемы, но после получения комментариев я понял, что моя проблема - это нечто иное).

Ниже приведены некоторые части кода.

ЧТЕНИЕ ДАННЫХ:

/** CODE DELETED */ 
while(fgets(line,MAXLINE,confFPtr) != NULL){ 

    /** CODE DELTED */ 

    /** if a command line then process the command */ 
    else if(line[0] == CMNDSTARTER){ 
     char *pathCommand = NULL;    /** stores path+command string */ 
     char *sha = NULL;      /** stores sha string */ 

     const char *separator = " "; /** delimiter between * command sha */ 
     char *arrayCommand[2];   /** stores path in one index and command in another string */ 

     /** tokenize the string */ 
     strtok(line,separator); 
     pathCommand = strtok(NULL,separator); 
     sha = strtok(NULL,separator); 

     /** Remove trailing space from end of hash */ 
     sha = preProcess(sha); 


     /** separate pathcommand into path and command */ 
     getPathCmd(arrayCommand,pathCommand); 

     /** add to list */ 
     /** List is a linked list */ 
     if(!addToList(cmdList,arrayCommand,sha)){ 

      printError("Silent Exit: couldn't add to list"); 
      exit(1); 
     } 


    } 

ВЫЧИСЛЕНИЕ СУММЫ для файла (команда, набран пользователем)

while(1){ 


    /** 
    * Read commands 
    */ 
    if(emitPrompt){ 
     printf("%s",prompt); 
     fflush(stdout); 
    } 

    if((fgets(cmdLine, MAXLINE, stdin) == NULL) && ferror(stdin)) 
     printError("fgets error"); 

    /** if ctrl-d pressed exit */ 
    if(feof(stdin)){ 
     fflush(stdout); 
     exit(0); 
    } 

    /** 
    * Remove trailing \n and preceding white space from user command 
    */ 
    processedCmdLine = preProcess(cmdLine); 

    /** If no command, continue */ 
    if(*processedCmdLine == 0) 
     continue; 
    /** check if the command entered by user is in the list of allowed commands */ 
    struct CMDList *s = searchList(cmdList,processedCmdLine); 

    /** if command was in the list, run checksum on the file and compare it with the stored checksum value */ 
    if(s != NULL){ 

     unsigned char hash[SHA_DIGEST_LENGTH]; 
     SHA1(processedCmdLine, sizeof(processedCmdLine),hash); 


    } 

} 

CMDList Структура

struct CMDList{ 

char *command; 
char *path; 
char *hash; 
struct CMDList *next; 

}; 

ответ

1

Я немного изменил свой код (код можно увидеть here). Проблема заключалась в том, что я хранили значения контрольной суммы в разных формах. Значение контрольной суммы из файла находится в виде простого текста, а при вычислении контрольной суммы будет возвращен символ unsigned. Поэтому я решил преобразовать возвращаемое значение контрольной суммы в его текстовую редакцию, а затем сравнить их с помощью strncmp(). Как видно, here.

1

Вы должны использовать

memcmp(hash1, hash2, SHA_DIGEST_LENGTH) 

Это не имеет значения, является ли ваш hash1 и hash2 являются char* или unsigned char* или любой смеси эфир. Хотя для консистенции приятно иметь их одного и того же типа:

struct CMDList{ 
    .... 
    unsigned char* hash; 
    ... 
}; 

Поскольку sha1 хэш фиксированной длины, вы можете точно также использовать

unsigned char hash[SHA_DIGEST_LENGTH]; 

и сохранить динамическое распределение.

Обратите внимание, что SHA_DIGEST_LENGTH равно 20, но 3848bdeada63dc59d2117a6ca1348fe0981ad2fc - это 40-символьная строка. Прежде чем вы сможете их использовать, вам нужно преобразовать читаемые значения хэша в двоичное представление.

+0

на ваше второе предложение о преобразовании значений хэша в двоичное представление, можете ли вы уточнить? спасибо, – Neo

+0

Обратите внимание, что строка хеш содержит одну шестнадцатеричную цифру ASCII на символ. Вам нужно будет преобразовать каждую пару таких цифр в одно целое число без знака в диапазоне от 0 до 255 и сохранить эти значения в массиве хеширования. –