При использовании 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)
```

Если проблема сохранится, попробуйте обратиться к документации по вашей библиотеке или к специальным форумам, связанным с продуктом, который вы используете.
<pre><code class="python">key = "letters1keydog963"
totp = pyotp.TOTP(key)</code></pre> <br/> <br/> Конструктор ожидает ключ, закодированный в <a href="https://datatracker.ietf.org/doc/html/rfc4648.html#section-6" rel="nofollow">Base32</a> , а там нет символов 0, 1, 8 и 9 (в <a href="https://pyauth.github.io/pyotp/#time-based-otps" rel="nofollow">документации</a> это как-то очень вскользь прописано). <br/> <br/> Для произвольных, в т.ч. бинарных, ключей используйте <code>base64.b32encode</code> . <br/> <br/> Как я понял, так они сделали ради <a href="https://github.com/google/google-authenticator/wiki/Key-Uri-Format#secret" rel="nofollow">совместимости с Google Authentificator</a> : <br/> <blockquote><br/>
<b>Parameters</b><br/>
<b>Secret</b><br/>
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.<br/>
</blockquote>
Похожие вопросы