При использовании PyOtp у вас возникает ошибка `binanscii.Error: Non-base 32 digit found`. Как можно решить эту проблему?

В приложении вместо кода отображаются только символы _ _ _   _ _ _: <br/>
  • 14 октября 2024 г. 21:32
Ответы на вопрос 2
Ошибка `binascii.Error: Non-base 32 digit found` возникает, когда в строке, которую вы пытаетесь декодировать в формате Base32, имеются символы, которые не соответствуют правилам этого формата. В частности, символы, разрешенные в Base32, — это буквы A-Z и цифры 2-7, а также символы для заполнения (обычно `=`).

Если вы видите только символы `_`, это может означать, что код, который вы пытаетесь расшифровать, имеет неверный формат или был поврежден. Вот несколько шагов для решения этой проблемы:

1. **Проверьте формат кода**:
   Убедитесь, что код, который вы используете, строго соответствует формату Base32. Например, вы можете использовать следующий набор символов: `ABCDEFGHIJKLMNOPQRSTUVWXYZ234567`.

2. **Удаление недопустимых символов**:
   Если в строке содержатся недопустимые символы, попробуйте удалить их или заменить на корректные. Например, вы можете попробовать заменить символы подчеркивания (`_`) на буквы, которые присутствуют в оригинальном коде.

3. **Использование окружения**:
   Если вы копируете код из какого-либо интерфейса, убедитесь, что при копировании не происходит искажений. Например, из-за пробелов или других символов.

4. **Заполнение**:
   Если длина строки, которую вы передаете для декодирования, не кратна 8, вам может понадобиться дополнить её символами `=` до кратности 8.

5. **Проверка на ошибки**:
   Если код генерируется программно, проверьте алгоритм генерации на наличие ошибок, которые могут привести к формированию неверных символов.

6. **Использование библиотеки**:
   Если вы используете библиотеки для работы с кодами (например, PyOTP), убедитесь, что они настроены правильно и совместимы с используемыми стандартами.

Пример кода для проверки строки Base32 на допустимые символы и исправления ошибки:

```python
import base64

def is_valid_base32(s):
    for char in s:
        if char not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=":
            return False
    return True

def decode_base32(s):
    # Замените '_' на '=' или уберите, если это недопустимый символ
    cleaned = s.replace('_', '')
    
    if not is_valid_base32(cleaned):
        raise ValueError("Invalid Base32 string")
    
    # Добавьте заполнение, если необходимо
    while len(cleaned) % 8 != 0:
        cleaned += '='

    return base64.b32decode(cleaned)

try:
    decoded = decode_base32(your_code_here)
    print(decoded)
except Exception as e:
    print("Error:", e)
```

Если проблема сохранится, попробуйте обратиться к документации по вашей библиотеке или к специальным форумам, связанным с продуктом, который вы используете.
key = "letters1keydog963"
totp = pyotp.TOTP(key)


Конструктор ожидает ключ, закодированный в Base32 , а там нет символов 0, 1, 8 и 9 (в документации это как-то очень вскользь прописано).

Для произвольных, в т.ч. бинарных, ключей используйте base64.b32encode .

Как я понял, так они сделали ради совместимости с Google Authentificator :

Parameters
Secret
REQUIRED: The secret parameter is an arbitrary key value encoded in Base32 according to RFC 3548. The padding specified in RFC 3548 section 2.2 is not required and should be omitted.
Похожие вопросы