Преобразование строки C в двоичное представление - PullRequest
3 голосов
/ 14 апреля 2011

Как в ANSI C преобразовать строку в массив двоичных байтов? Все поиски и поиск дают мне ответы на C ++ и другие, а не на C.

У меня была одна идея - преобразовать строку в ASCII, а затем преобразовать каждое значение ASCII в его двоичный файл. (Дух!) Я знаю, что это самые глупые идеи, но я не уверен ни в каком другом варианте.

Я слышал о функции кодирования в Java. Я не уверен, что это соответствует той же цели и может быть принято к C.

string = "Hello"
bytearr[] = 10100101... some byte array..

Было бы замечательно, если бы кто-то смог пролить свет на это.

Спасибо!

Ответы [ 6 ]

8 голосов
/ 14 апреля 2011

Или вы имели в виду, как преобразовать строку C в двоичное представление?

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

#include <stdio.h>

int main(int argc, char *argv[])
{
    if(argv[1] == NULL) return 0; /* no input string */

    char *ptr = argv[1];
    int i;

    for(; *ptr != 0; ++ptr)
    {
        printf("%c => ", *ptr);

        /* perform bitwise AND for every bit of the character */
        for(i = 7; i >= 0; --i) 
            (*ptr & 1 << i) ? putchar('1') : putchar('0');

        putchar('\n');
    }

    return 0;
}

Пример ввода и вывода:

./ascii2bin hello

h => 01101000
e => 01100101
l => 01101100
l => 01101100
o => 01101111
3 голосов
/ 14 апреля 2011

В C. нет никаких строк. Любая строка является массивом байтов.

1 голос
/ 14 апреля 2011

В большинстве систем, над которыми я работал, ширина char составляет 1 байт, поэтому char[] или char* - это байтовый массив.

В большинстве других языков, таких как Java, строковый тип данных позаботится о том, чтобы в определенной степени заботиться о таких понятиях, как кодирование, используя кодировку, например UTF-8. В С это не так. Если бы я прочитал строку UTF-8, содержимое которой включало многобайтовые значения, мои символы были бы представлены двумя сегментами в массиве (или, возможно, больше).

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

Таким образом, строка, с которой вы работаете , является байтовым массивом.

Следующий вопрос, наверное, как вы отображаете эти байты? Это довольно просто:

char* x = ???; /* some string */
unsigned int xlen = strlen(x);
int i = 0;

for ( i = 0; i < xlen; i++ )
{
    printf("%x", x[i]);
}

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

1 голос
/ 14 апреля 2011

Строка является массивом байтов.

Если вы хотите отобразить значение ASCII каждого символа в шестнадцатеричной форме, вы просто сделаете что-то вроде:

while (*str != 0)
  printf("%02x ", (unsigned char) *str++);
0 голосов
/ 07 мая 2011

Поскольку printf работает медленно при преобразовании огромного двоичного массива.Вот другой подход, который не использует printf:

#define BASE16VAL               ("x0x1x2x3x4x5x6x7x8x9|||||||xAxBxCxDxExF") 
#define BASE16_ENCODELO(b)      (BASE16SYM[((uint8)(b)) >> 4])
#define BASE16_ENCODEHI(b)      (BASE16SYM[((uint8)(b)) & 0xF]) 
#define BASE16_DECODELO(b)      (BASE16VAL[Char_Upper(b) - '0'] << 4)
#define BASE16_DECODEHI(b)      (BASE16VAL[Char_Upper(b) - '0']). 

Чтобы преобразовать шестнадцатеричную строку в байтовый массив, вы должны сделать следующее:

while (*Source != 0)   
    {   
    Target[0]  = BASE16_DECODELO(Souce[0]);   
    Target[0] |= BASE16_DECODEHI(Souce[1]);    

    Target += 1;   
    Source += 2;   
    } 

*Target = 0;

Источник - указатель на символмассив, который содержит шестнадцатеричную строку.Target - это указатель на массив символов, который будет содержать байтовый массив.

Чтобы преобразовать байтовый массив в шестнадцатеричную строку, вы должны сделать следующее:

while (*Source != 0)   
    {   
    Target[0] = BASE16_ENCODELO(*Source);   
    Target[1] = BASE16_ENCODEHI(*Source);    

    Target += 2;   
    Source += 1;   
    }

Target - это указатель намассив символов, содержащий шестнадцатеричную строку.Source - указатель на массив символов, который будет содержать байтовый массив.

Вот несколько отсутствующих макросов:

#define Char_IsLower(C)  ((uint8)(C - 'a') < 26)
#define Char_IsUpper(C)  ((uint8)(C - 'A') < 26)
#define Char_Upper(C)    (Char_IsLower(C) ? (C + ('A' - 'a')) : C)
#define Char_Lower(C)    (Char_IsUpper(C) ? (C + ('a' - 'A')) : C)
0 голосов
/ 14 апреля 2011

Если вы просто хотите перебрать (или получить произвольный доступ) числовые значения отдельных байтов, вам вообще не нужно выполнять никаких преобразований, поскольку строки C уже являются массивами:

void dumpbytevals(const char *str)
{
    while (*str)
    {
        printf("%02x ", (unsigned char)*str);
        str++;
    }
    putchar('\n');
}

Если вывы не осторожны с этим типом кода, тем не менее, вы рискуете оказаться в мире вреда, когда вам нужно поддерживать символы не-ASCII.

...