Значение фактического кодированного идентификатора ASCII85 должно быть:
T,irMU)?YQSB"#'3>>Cq
В значении не должно быть \
.Неправильно ваше преобразование результата a85encode()
в строку:
str(bs64.a85encode(bytearray.fromhex(id)))[2:-1]
a85encode()
возвращает объект bytes
, вам необходимо декодировать , что, как ASCII,чтобы получить строковое значение с теми же кодовыми точками:
bs64.a85encode(bytearray.fromhex(id)).decode('ASCII')
str(bytesobject)
дает удобное для отладки представление , которое безопасно вставить обратно в код Python, поэтому любой '
символы экранируются с \
впереди.Вы не хотите использовать это представление для сериализации.
Обратите внимание, что вам не нужен bytearray
, обычного неизменяемого объекта bytes
достаточно для декодирования шестнадцатеричного идентификатора в двоичную строку:
bs64.a85encode(bytes.fromhex(id)).decode('ASCII')
Демонстрация:
>>> import base64 as b64
>>> id = '9F1D8E8BA2194CD29CC744083914535A'
>>> encoded = bs64.a85encode(bytes.fromhex(id)).decode('ASCII')
>>> print(encoded)
T,irMU)?YQSB"#'3>>Cq
>>> b64.a85decode(encoded).hex()
'9f1d8e8ba2194cd29cc744083914535a'
Если вы не можете восстановить кодировку, вы все равно можете восстановить поврежденные значения с помощью кодека unicode_escape
;сначала закодируйте строку в ASCII.Вы должны быть в состоянии обнаружить такое неработающее значение, проверив длину: 20-байтовый IDFA всегда должен приводить к 20-символьной строке ASCII85, все, что больше нуждается в исправлении:
if len(docId) > 20:
docId = docId.encode('ascii').decode('unicode_escape')
decoded = b64.a85decode(docId).hex()
Выше исправлены ошибкивведено путем вызова str()
для объекта байтов:
>>> encoded
'T,irMU)?YQSB"#\'3>>Cq'
>>> botched = str(encoded.encode('ascii'))[2:-1]
>>> botched
'T,irMU)?YQSB"#\\\'3>>Cq'
>>> botched.encode('ascii').decode('unicode_escape')
'T,irMU)?YQSB"#\'3>>Cq'
>>> bs64.a85decode(botched.encode('ascii').decode('unicode_escape')).hex()
'9f1d8e8ba2194cd29cc744083914535a'
Обратите внимание, что если вы работаете со значениями IDFA, вы можете использовать uuid.UUID()
класс для преобразования между представлениями:
from uuid import UUID
bs64.a85encode(UUID(hex=id).bytes).decode('ASCII')
для кодирования и
str(UUID(bytes=bs64.a85decode(docId)))
для возврата к шестнадцатеричной строке 8-4-4-4-12 с тире:
>>> from uuid import UUID
>>> id = '9F1D8E8B-A219-4CD2-9CC7-44083914535A'
>>> encoded = bs64.a85encode(UUID(hex=id).bytes).decode('ASCII')
>>> encoded
'T,irMU)?YQSB"#\'3>>Cq'
>>> str(UUID(bytes=bs64.a85decode(encoded)))
'9f1d8e8b-a219-4cd2-9cc7-44083914535a'