QR-кодирование с битовыми полями

Я пытаюсь выполнить упражнение на языке C, целью которого является кодирование сообщения в QR-коде 2Q с помощью метода байтов. Это означает, что данная строка должна быть закодирована в сообщении с помощью:

  • 4 бита для индикатора режима (в моем случае 0100);
  • 8 бит для длины сообщения;
  • само сообщение (20 символов);
  • 4 нулевых бита как сигнал конца сообщения;
  • 16 бит для заполнения 0xEC11.

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

typedef struct
{
  unsigned char mode   : 4;
  unsigned int length  : 8;
  unsigned char *message;
  unsigned char eof    : 4;
  unsigned int padding : 16;
} code;

Я также попытался сдвинуть биты закодированного сообщения влево, но снова получил сообщение об ошибке «Ожидаемое значение int», что означает (если я правильно понял) я не могу сдвинуть структуру.

Может ли кто-нибудь предложить элегантный способ выполнения этой задачи?

Вы не можете использовать битовые поля для отображения битов. Они просто слишком сломаны по замыслу. Вместо этого используйте массив uint8_t[n] для хранения данных, а затем проанализируйте его оттуда. У вас также может быть соответствующая структура, если вы можете надежно отключить заполнение структур в своем компиляторе - иначе структуры не будут работать без процедур сериализации / десериализации.

Lundin 11.12.2018 13:43

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

user694733 11.12.2018 13:46

Как говорит @ user694733, это поток биты, а не поток байты. Предполагая, что 8 бит / байт, эти 4-битные поля в данных действительно создают проблему - чтобы получить биты в правильном порядке, вам придется учитывать порядок байтов системы в каждом из байтов данных.

Andrew Henle 11.12.2018 16:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
103
1

Ответы 1

В конце концов я реализовал это с данными в uint8_t и битовым сдвигом. Это означает, что я сохранил строку в массиве, а затем сдвинул ее, как показано ниже:

for(int n_digit = 0; n_digit <= length; n_digit++)
{
    if (n_digit < length)
    {
        *(code + n_digit) = (*(code + n_digit) << 4) + (*(code + n_digit + 1) >> 4);
    }
    else if (n_digit == length)
    {
        *(code + n_digit) = *(code + n_digit) << 4;
    }
}

Возможно, код не самого высокого качества, но работает отлично.

Другие вопросы по теме