Это делает "глубоко" проверки, проверки, что контрольная сумма, встроенная в каждый Bitcoin адрес совпадает с адресом. Она нуждается в библиотеке PyCrypto для функции SHA256.
Я передаю этот код в общественное достояние, делать с ним что угодно. И, пожалуйста, дайте мне знать, если вы обнаружите какие-либо ошибки в нем.
BCAddressField.py:
Код:
#
# Джанго типа поля для Bitcoin Адреса
#
импорт повторно
от Джанго импортных форм
от django.forms.util импорта ValidationError
от Crypto.Hash импорта SHA256
Класс BCAddressField (forms.CharField):
default_error_messages = {
'Недействителен': 'Invalid Bitcoin адрес.',
}
Защиту __init __ (самоповреждения, * Args, ** kwargs):
супер (BCAddressField, самость) .__ INIT __ (* Args, ** kwargs)
Защиту чистый (я, значение):
значение = value.strip ()
если re.match (г"[A-Za-Z1-9] {27,35} $", Значение) не None:
поднять ValidationError (self.error_messages [ 'недействителен'])
версия = get_bcaddress_version (значение)
если версия не None:
поднять ValidationError (self.error_messages [ 'недействителен'])
возвращаемое значение
импорт математика
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = Len (__ b58chars)
Защиту b58encode (v):
""" закодировать v, который является строка байтов, в base58.
"""
LONG_VALUE = 0L
для (I, с) в Перечислим (V [:: - 1]):
LONG_VALUE + = (256 ** я) * Ord (с)
Результат = «»
в то время как LONG_VALUE >= __b58base:
ДИВ, мод = divmod (LONG_VALUE, __b58base)
Результат = __b58chars [мод] + результат
LONG_VALUE = DIV
Результат = __b58chars [LONG_VALUE] + результат
# Bitcoin делает немного опережените нулевое сжатие:
# Ведущих 0-байты на входе становятся ведущим-1s
NPAD = 0
для с в V:
если с == '\ 0': NPAD + = 1
еще: разрыв
возврата (__b58chars [0] * NPAD) + результат
Защиту b58decode (V, длина):
""" расшифровывает v в строку LEN байтов
"""
LONG_VALUE = 0L
для (I, с) в Перечислим (V [:: - 1]):
LONG_VALUE + = __b58chars.find (с) * (__b58base ** я)
Результат = «»
в то время как LONG_VALUE >= 256:
DIV, MOD = divmod (LONG_VALUE, 256)
Результат = CHR (моды) + результат
LONG_VALUE = DIV
Результат = CHR (LONG_VALUE) + результат
NPAD = 0
для с в V:
если с == __b58chars [0]: NPAD + 1 =
еще: разрыв
Результат = CHR (0) * NPAD + результат
если длина не является None и LEN (результат) = длина:
возвращения None
возвращаемый результат
Защиту get_bcaddress_version (strAddress):
""" Возвращает None, если strAddress является недействительным. В противном случае возвращает целочисленную версию адреса. """
адр = b58decode (strAddress, 25)
если адрес не None: возвращение None
версия = ADDR [0]
Контрольная сумма = ADDR [-4]:
vh160 = адр [: - 4] # Version плюс hash160 является то, что контрольная сумма
h3 = SHA256.new (SHA256.new (vh160) .digest ()). дайджеста ()
если h3 [0: 4] == Контрольная сумма:
Возвращение ог (версия)
возвращения None
20 октября: Исправлена ошибка с Bitcoin адреса с ведущими-1-х.# Джанго типа поля для Bitcoin Адреса
#
импорт повторно
от Джанго импортных форм
от django.forms.util импорта ValidationError
от Crypto.Hash импорта SHA256
Класс BCAddressField (forms.CharField):
default_error_messages = {
'Недействителен': 'Invalid Bitcoin адрес.',
}
Защиту __init __ (самоповреждения, * Args, ** kwargs):
супер (BCAddressField, самость) .__ INIT __ (* Args, ** kwargs)
Защиту чистый (я, значение):
значение = value.strip ()
если re.match (г"[A-Za-Z1-9] {27,35} $", Значение) не None:
поднять ValidationError (self.error_messages [ 'недействителен'])
версия = get_bcaddress_version (значение)
если версия не None:
поднять ValidationError (self.error_messages [ 'недействителен'])
возвращаемое значение
импорт математика
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = Len (__ b58chars)
Защиту b58encode (v):
""" закодировать v, который является строка байтов, в base58.
"""
LONG_VALUE = 0L
для (I, с) в Перечислим (V [:: - 1]):
LONG_VALUE + = (256 ** я) * Ord (с)
Результат = «»
в то время как LONG_VALUE >= __b58base:
ДИВ, мод = divmod (LONG_VALUE, __b58base)
Результат = __b58chars [мод] + результат
LONG_VALUE = DIV
Результат = __b58chars [LONG_VALUE] + результат
# Bitcoin делает немного опережените нулевое сжатие:
# Ведущих 0-байты на входе становятся ведущим-1s
NPAD = 0
для с в V:
если с == '\ 0': NPAD + = 1
еще: разрыв
возврата (__b58chars [0] * NPAD) + результат
Защиту b58decode (V, длина):
""" расшифровывает v в строку LEN байтов
"""
LONG_VALUE = 0L
для (I, с) в Перечислим (V [:: - 1]):
LONG_VALUE + = __b58chars.find (с) * (__b58base ** я)
Результат = «»
в то время как LONG_VALUE >= 256:
DIV, MOD = divmod (LONG_VALUE, 256)
Результат = CHR (моды) + результат
LONG_VALUE = DIV
Результат = CHR (LONG_VALUE) + результат
NPAD = 0
для с в V:
если с == __b58chars [0]: NPAD + 1 =
еще: разрыв
Результат = CHR (0) * NPAD + результат
если длина не является None и LEN (результат) = длина:
возвращения None
возвращаемый результат
Защиту get_bcaddress_version (strAddress):
""" Возвращает None, если strAddress является недействительным. В противном случае возвращает целочисленную версию адреса. """
адр = b58decode (strAddress, 25)
если адрес не None: возвращение None
версия = ADDR [0]
Контрольная сумма = ADDR [-4]:
vh160 = адр [: - 4] # Version плюс hash160 является то, что контрольная сумма
h3 = SHA256.new (SHA256.new (vh160) .digest ()). дайджеста ()
если h3 [0: 4] == Контрольная сумма:
Возвращение ог (версия)
возвращения None