Создайте файл, который использует 4-битное кодирование для представления целых чисел 0 -9 - PullRequest
0 голосов
/ 27 февраля 2011

Как мне создать файл, который использует 4-битную кодировку для представления целых чисел 0-9, разделенных запятой ('1111')? например:

2,34,99 = 0010 1111 0011 0100 1111 1001 1001 => фактически становится без пробелов 0010111100110100111110011001 = binary.txt

Поэтому 0010111100110100111110011001 - это то, что я вижу при просмотре файла ('binary.txt') в WINHEX в двоичном представлении, но я вижу 2,34,99 при просмотре файла (binary.txt) в Блокноте.

Если не Блокнот, есть ли другой декодер, который будет выполнять 4-битное кодирование, или у меня есть программа-декодер для просмотра целых чисел?

Как я могу сделать это в C ++?

Ответы [ 3 ]

1 голос
/ 27 февраля 2011

Основная идея вашего формата (4 бита на десятичную цифру) хорошо известна и называется BCD (Binary Coded Decimal).Но я сомневаюсь, что использование 0xF в качестве кодировки для комы является чем-то устоявшимся и даже более поддерживаемым блокнотом.

Написание программы на C ++ для кодирования и декодирования было бы довольно легко.Единственная трудность состоит в том, что стандартный ввод-вывод использует байт как более базовую единицу, а не бит, поэтому вам придется сгруппировать биты в байт.

0 голосов
/ 27 февраля 2011

Это самый простой алгоритм C ++ 4-битного (BCD) кодирования, который я мог придумать - его бы не назвать простым, но не ракетостроение. Извлекает по одной цифре за раз, а затем добавляет их в строку:

#include <iostream>

int main() {
const unsigned int ints = 3;
unsigned int a[ints] = {2,34,99}; // these are the original ints
unsigned int bytes_per_int = 6;
char * result = new char[bytes_per_int * ints + 1];
// enough space for 11 digits per int plus comma, 8-bit chars
for (int j=0; j < bytes_per_int * ints; ++j)
{
    result[j] = 0xFF; // fill with FF
}
result[bytes_per_int*ints] = 0; // null terminated string

unsigned int rpos = bytes_per_int * ints * 2; // result position, start from the end of result
int i = ints; // start from the end of the array too.
while (i != 0) {
    --i;
    unsigned int b = a[i];
    while (b != 0) {
       --rpos;
       unsigned int digit = b % 10; // take the lowest decimal digit of b
       if (rpos & 1) {
           // odd rpos means we set the lowest bits of a char
           result[(rpos >> 1)] = digit;
       }
       else {
           // even rpos means we set the highest bits of a char
           result[(rpos >> 1)] |= (digit << 4);
       }
       b /= 10; // make the next digit the new lowest digit
    }
    if (i != 0 || (rpos & 1))
    {
       // add the comma
       --rpos;
       if (rpos & 1) {
           result[(rpos >> 1)] = 0x0F;
       }
       else {
           result[(rpos >> 1)] |= 0xF0;
       }
    }
}
std::cout << result;
}

Обрезка фиктивных данных, оставленных в начальной части результата в соответствии с rpos, будет оставлена ​​в качестве упражнения для читателя.

Подзадача преобразования BCD также обсуждалась ранее: Беззнаковое целое в преобразование BCD?

Если вам нужен более эффективный алгоритм, вот несколько слайдов лекций с преобразованием из 8-битных целых в BCD: http://edda.csie.dyu.edu.tw/course/fpga/Binary2BCD.pdf

0 голосов
/ 27 февраля 2011

Вы можете декодировать файлы, используя od -tx1, если у вас есть (цифры будут отображаться как цифры, запятые будут отображаться как f). Вы также можете использовать xxd, чтобы идти в обоих направлениях; это идет с Vim. Используйте xxd -r -p, чтобы скопировать шестнадцатеричные символы из stdin в двоичный файл на stdout, и xxd -p, чтобы пойти другим путем. Вы можете использовать sed или tr, чтобы изменить f вперед и назад на ,.

...