Как упростить или сделать повторяющийся код более эффективным? - PullRequest
0 голосов
/ 03 февраля 2020

Из приведенного ниже примера кода видно, что первая функция 1 (concat_1) практически идентична функции 2 (concat_2). Единственное отличие состоит в том, что на 1 строку больше SHA512_Update (& c, d, strlen ((char *) d)).

Мой вопрос заключается в том, как превратить эти функции в 1, чтобы код не повторится. Я считаю, что разница в 1 строку - это пустая трата ресурсов, и ее следует исправить.

Примечание: каждая функция требует поддержки библиотеки openssl для воспроизведения кода.

uint8_t md[SHA512_DIGEST_LENGTH] = {0};
uint8_t a[] = "a";
uint8_t b[] = "b";
uint8_t x[] = "x";
uint8_t d[] = "d";


void concat_1(uint8_t *md, uint8_t *a, uint8_t *b, uint8_t *x)
{
    SHA512_CTX c;
    SHA512_Init(&c);

    SHA512_Update(&c, a, strlen((char*)a);
    SHA512_Update(&c, b, strlen((char*)b);
    SHA512_Update(&c, x, strlen((char*)x);

    SHA512_Final(md, &c);

}

void concat_2(uint8_t *md, uint8_t *a, uint8_t *b, uint8_t *x, uint8_t *d)
{
    SHA512_CTX c;
    SHA512_Init(&c);

    SHA512_Update(&c, a, strlen((char*)a);
    SHA512_Update(&c, b, strlen((char*)b);
    SHA512_Update(&c, x, strlen((char*)x));
    SHA512_Update(&c, d, strlen((char*)d));

    SHA512_Final(md, &c);

}

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

Вы можете добавить аргумент, указывающий, какой из двух случаев вы хотите.

void concat(int is_type_2, uint8_t *md, uint8_t *a, uint8_t b, uint8_t *x, uint8_t *d)
{
    SHA512_CTX c;
    SHA512_Init(&c);

    SHA512_Update(&c, a, strlen((char*)a));
    SHA512_Update(&c, b, strlen((char*)b));
    SHA512_Update(&c, x, strlen((char*)x));

    if (is_type_2)
        SHA512_Update(&c, d, strlen((char*)d));

    SHA512_Final((uint8_t*)md, &c);

}

И затем добавить пару макросов, чтобы вы могли по-прежнему вызывать concat_1 и concat_2, как и прежде слияние:

#define concat_1(...) concat(0, __VA_ARGS__, 0)
#define concat_2(...) concat(1, __VA_ARGS__) 
1 голос
/ 04 февраля 2020

Вы можете обобщить подпрограмму, используя списки переменных переменных:

#include <stdarg.h>

void concat(uint8_t *md, const uint8_t *x,...)
{
    SHA512_CTX c;
    SHA512_Init(&c);

    // Create and initialize a va_list to access the arguments.
    va_list ap;
    va_start(ap, x);

    // Continue while arguments are not null.
    while (x)
    {
        // Update with current argument’s text.
        SHA512_Update(&c, x, strlen((const char *) x));

        // Get next argument.
        x = va_arg(ap, const uint8_t *);
    }
    va_end(ap);

    SHA512_Final(md, &c);
}

Затем вы можете вызвать ее с помощью NULL завершенного списка аргументов:

concat(md, a, NULL);
concat(md, a, b, c, NULL);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...