Кодирование числа путем редактирования последнего бита элементов массива - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь написать простую программу кодирования на C, и у меня определенно что-то не так с моими побитовыми операциями, поэтому я попытался написать упрощенную версию, чтобы исправить эту ошибку - пока она все еще не работает.У меня есть метод кодирования и декодирования, где, учитывая «ключ», я кодирую одно число, скрывая его биты в большом массиве беззнаковых целых.

Я скрываю это, используя srand (ключ) (чтобы я мог генерировать одинаковые числа после слова с одним и тем же ключом), выбирая элементы массива, а затем беря один бит числа (перебирая все) и меняя местами наименее значимыебит элемента массива для бита, проходящего через число.

В методе декодирования я пытаюсь сторнировать шаги, вернуть все биты из элементов массива и склеить их, чтобы получить исходное число.

Это код, который у меня есть:

    unsigned int * encode(unsigned int * original_array, char * message, unsigned int mSize, unsigned int secret) {//disregard message, that's the later part, for now just encoding mSize - size of message

    int size = MAX; //amount of elementas in array, max defined at top
    int i, j, tmp;
    unsigned int *array;


    srand(secret); //seed rand with the given key

    array = (unsigned int *)malloc(MAX*sizeof(unsigned int));
    //copy to array from im
    for (i=0; i<MAX; i++){
        array[i] = original_array[i];
    }

    //encode message length first. it's a unsigned int therefore it's size is 4 bytes - 32 bits.

    for (i=0; i<32; i++){
        tmp = rand() % size;
        if (((mSize >> i) & 1)==1) //check if the bit is 1
            array[tmp] = (1 << 0) | array[tmp]; // then write 1 as last bit 
        else //else bit is 0
            array[tmp] = array[tmp] & (~(1 << 0)); //write 0 as last bit 

    }

    return array;
}

unsigned int decode(unsigned int * im, unsigned int secret) {
    char * message;
    int i, tmp;
    unsigned int result = 2;
    int size = MAX;


    srand(secret);
    for (i=0; i<32; i++){
        tmp = rand() % size;
        if (((im[tmp] << 0) & 1)==1)
            result = (1 >> i) | result;
        else
            result = result & (~(1 >> i));
        }//last 

    return result;
}

Однако, если запустить его и попытаться напечатать декодированный результат, я получу 2, что является фиктивным значением, которое я дал для результата в decode (), поэтому язнаю, что по крайней мере мой метод восстановления измененных битов явно не работает.К сожалению, поскольку декодирование не работает, я понятия не имею, действительно ли работает кодирование, и я не могу точно определить ошибку.

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

Редактировать: в результате некоторой отладки я думаю, что кодированиеФункция работает правильно - или, по крайней мере, кажется, иногда изменяет элементы массива на один, что указывало бы на переключение одного бита, если выполняются условия.Похоже, что декодирование вообще не влияет на переменную result - оно не меняет всех ваших побитовых операций, и я не знаю почему.

1 Ответ

0 голосов
/ 26 февраля 2019

Основной бит функции кодирования - это то же самое, что ваш оригинал, только немного убрав его, удалив ненужные 0 сдвигов и скобок:

//encode message length first. it's a unsigned int therefore it's size is 4 bytes - 32 bits.
for (i=0; i<32; i++){
    tmp = rand() % size;
    if (((mSize >> i) & 1)==1) //check if the bit is 1
        array[tmp] |= 1; // then write 1 as last bit 
    else //else bit is 0
        array[tmp] &= ~1; //write 0 as last bit 
}

Проблема, с которой вы сталкиваетесьлибо установите последний бит на 1 или 0, тогда вы фактически потеряете информацию.Невозможно сказать, какой был последний последний бит.И поэтому вы не сможете его декодировать или перевернуть.

Короче говоря, функция декодирования никогда не будет работать.Поскольку функция кодирования не является обратимой.

РЕДАКТИРОВАТЬ

Исходя из вашего комментария.Я бы сказал следующее о функции декодирования (опять же приведено в порядок, это должно быть то же самое, что и оригинал):

unsigned int decode(unsigned int * im, unsigned int secret) {
    char * message;
    int i, tmp;
    unsigned int result = 2;
    int size = MAX;


    srand(secret);
    for (i=0; i<32; i++){
        tmp = rand() % size;
        if ((im[tmp] & 1)==1)
            result |= 1 >> i;
        else
            result &= ~(1 >> i);
        }//last 

    return result;
}

Здесь следует отметить, что для всех значений i> 0 будет применяться следующее:

1 >> i

совпадает с

0

Это означает, что дляБольшую часть вашего цикла код будет делать следующее

if ((im[tmp] & 1)==1)
    result |= 0;
else
    result &= ~0;

И так как 2 = 2 |0 и 2 = 2 & ~ 0, то независимо от того, какая ветвь оператора if выполнена, результат всегда будет равен 2. Это будет то же самое для любого четного числа.

Когда i = 0, то следующееcase:

if ((im[tmp] & 1)==1)
    result |= 1;
else
    result &= ~1;

И так с 2 |1 = 3 и 2 & ~ 1 = 2 ваша функция декодирования будет возвращать только 2 или иногда 3.

...