Базовое кодирование невозможно с ведущим 0?

0

Я пытаюсь кодировать строку в base36.

static char *decode(unsigned long long value)
{
    char base36[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char buffer[14];
    unsigned int offset = sizeof(buffer);

    buffer[--offset] = '\0';
    do {
        buffer[--offset] = base36[value % 36];
    } while (value /= 36);

    return _strdup(&buffer[offset]);
}

int main()
{
    char original[8] = "0XDX3A1";
    unsigned long long encoded = _strtoui64(original, NULL, 36);
    char *decoded = decode(encoded);

    cout << "Original: " << original << " Decoded: " << decoded << endl;
    return 0;
}

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

Как с этим бороться?

  • 1
    Какое отношение имеет код к вопросу о декодировании ? Покажите код декодирования и строку, которую вы декодируете.
  • 0
    Вы спрашиваете, почему значение 07 кодируется так же, как значение 7?
Показать ещё 19 комментариев
Теги:

4 ответа

1
Лучший ответ
  • zeroCount новую переменную в ваш основной, называемый zeroCount в main
  • Ввести второй аргумент для функции decode, называемый zeroCount
  • Подсчитайте количество zeroCount нулей в original на zeroCount в main
  • Поместите нули в buffer[--offset] пока вы не будете потреблять весь zeroCount перед return

Как это:

static char *decode( unsigned long long value, int zeroCount )  
{           // introduced zeroCount argument there ^
    char base36[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char buffer[14];
    unsigned int offset = sizeof( buffer );

    buffer[--offset] = '\0';
    do {
        buffer[--offset] = base36[value % 36];
    } while ( value /= 36 );

    while ( zeroCount-- ) buffer[--offset] = '0';   // <-- added this

    return strdup( &buffer[offset] );
}

int main( )
{
    char original[8] = "0XDX3A1";
    unsigned long long encoded = _strtoui64( original, NULL, 36 );

    int zeroCount = 0;                                                  // added
    for ( int i = 0; i < sizeof original && original[i] == '0'; i++ )   // these
        zeroCount++;                                                    // three

    char *decoded = decode( encoded, zeroCount );   // <-- called along with zeroCount


    cout << "Original: " << original << " Decoded: " << decoded << endl;
    return 0;
}

Поскольку нет никакого очевидного правила для желаемого поведения 0 вам нужно, я должен был предположить, что вы хотели бы иметь много ведущих нулей, которые были у original.

  • 0
    Хорошо, сейчас это не так, я исправляю это ...
  • 0
    Больше нет ... Ну, это было глупо с моей стороны, я думал, что инициализированные 0 с будут печататься как 0 с, но, конечно же, нет, они скорее должны быть превращены в '0' . Работает довольно хорошо прямо сейчас.
Показать ещё 2 комментария
4

Если вы декодируете строку "01234" в качестве строки base-16 (например), вы получаете целочисленное значение 4660 (0x1234) - точно такое же целочисленное значение, которое вы получаете, декодируя строку "1234" или "00001234" как base-16. Преобразуя строку в целое число, вы выбросили любую информацию о ведущих нулях. Вы также отбросили любую информацию о прописных и строчных букв, считая, что A и a представляют одно и то же значение.

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

  • 0
    Я вижу, но как можно добавить ведущие 0, если я не знаю размер строки?
  • 2
    @Luka: Вы не можете. Если вы хотите воссоздать исходную строку, вам необходимо хранить достаточно информации об исходной строке.
Показать ещё 4 комментария
1

Вы вызываете функцию tat, которая принимает строку, содержащую представление числового значения, и преобразует ее в unsigned long long. Два строковых представления "00007" и "7" оба преобразуются в числовые 7, а ведущие нули теряются.

Если вы хотите, например, 00000036, чтобы скрыть до 00000010 в базе 36, вам просто нужно подсчитать нули, которые вы хотите, а затем решить, сколько из них нужно заменить (зависит ли это от относительной длины базовых 10 и базовых 36 строк?)

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

  • 0
    Я думаю, что вы имеете в виду «добавить ведущие нули», а не «добавить конечные нули».
  • 0
    @KeithThompson Wat? Потратили некоторое время, чтобы увидеть разницу, разве эти две последовательности слов не идентичны?
Показать ещё 3 комментария
0

Я предлагаю вам создать обертку вокруг вашего метода и передать ей параметр длины.

Например.

char * wrap_base36enc(int out_len, unsigned long long value){
    char pre_str[MAX_VAL]="", *ans = base36enc(value);
    len -= strlen(ans);

    while(len--){
     strcat(pre_str,"0");
    }
    strcat(pre_str,ans);

    return pre_str;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню