def __resolve_connection_conflict(self, handler, h_id): # type: (MeshSocket, BaseConnection, bytes) -> None """Sometimes in trying to recover a network a race condition is created. This function applies a heuristic to try and organize the fallout from that race condition. While it isn't perfect, it seems to have increased connection recovery rate from ~20% to ~75%. This statistic is from memory on past tests. Much improvement can be made here, but this statistic can likely never be brought to 100%. In the failure condition, the overall network is unaffected *for large networks*. In small networks this failure condition causes a fork, usually where an individual node is kicked out. Args: handler: The handler with whom you have a connection conflict h_id: The id of this handler """ self.__print__("Resolving peer conflict on id %s" % repr(h_id), level=1) to_kill = to_keep = None # type: Union[None, BaseConnection] if (bool(b58decode_int(self.id) > b58decode_int(h_id)) ^ bool(handler.outgoing)): # logical xor self.__print__("Closing outgoing connection", level=1) to_keep, to_kill = self.routing_table[h_id], handler self.__print__(to_keep.outgoing, level=1) else: self.__print__("Closing incoming connection", level=1) to_keep, to_kill = handler, self.routing_table[h_id] self.__print__(not to_keep.outgoing, level=1) self.disconnect(cast(MeshConnection, to_kill)) self.routing_table.update({h_id: to_keep})
def __resolve_connection_conflict(self, handler, h_id): # type: (MeshSocket, BaseConnection, bytes) -> None """Sometimes in trying to recover a network a race condition is created. This function applies a heuristic to try and organize the fallout from that race condition. While it isn't perfect, it seems to have increased connection recovery rate from ~20% to ~75%. This statistic is from memory on past tests. Much improvement can be made here, but this statistic can likely never be brought to 100%. In the failure condition, the overall network is unaffected *for large networks*. In small networks this failure condition causes a fork, usually where an individual node is kicked out. Args: handler: The handler with whom you have a connection conflict h_id: The id of this handler """ self.__print__( "Resolving peer conflict on id %s" % repr(h_id), level=1) to_kill = to_keep = None # type: Union[None, BaseConnection] if (bool(b58decode_int(self.id) > b58decode_int(h_id)) ^ bool(handler.outgoing)): # logical xor self.__print__("Closing outgoing connection", level=1) to_keep, to_kill = self.routing_table[h_id], handler self.__print__(to_keep.outgoing, level=1) else: self.__print__("Closing incoming connection", level=1) to_keep, to_kill = handler, self.routing_table[h_id] self.__print__(not to_keep.outgoing, level=1) self.disconnect(cast(MeshConnection, to_kill)) self.routing_table.update({h_id: to_keep})
def _fulfillment_from_details(data, _depth=0): """ Load a fulfillment for a signing spec dictionary Args: data: tx.output[].condition.details dictionary """ if _depth == 100: raise ThresholdTooDeep() if data['type'] == 'ed25519-sha-256': public_key = base58.b58decode(data['public_key']) return Ed25519Sha256(public_key=public_key) if data['type'] == 'rsa-sha-256': m_int = base58.b58decode_int(data['public_key']) m_bytes = m_int.to_bytes( (m_int.bit_length() + 7) // 8, 'big' ) rsa_sha256 = RsaSha256() rsa_sha256._set_public_modulus(m_bytes) return rsa_sha256 if data['type'] == 'threshold-sha-256': threshold = ThresholdSha256(data['threshold']) for cond in data['subconditions']: cond = _fulfillment_from_details(cond, _depth+1) threshold.add_subfulfillment(cond) return threshold raise UnsupportedTypeError(data.get('type'))
def __handle_retrieve(self, msg, handler): # type: (ChordSocket, Message, BaseConnection) -> Union[bool, None] """This callback is used to deal with data retrieval signals. Its two primary jobs are: - respond with data you possess - if you don't possess it, make a request with your closest peer to that key Args: msg: A :py:class:`~py2p.base.Message` handler: A :py:class:`~py2p.chord.ChordConnection` Returns: Either ``True`` or ``None`` """ packets = msg.packets if packets[0] == flags.retrieve: if sanitize_packet(packets[1]) in hashes: val = self.__lookup(sanitize_packet(packets[1]), b58decode_int(packets[2]), cast(ChordConnection, handler)) if val.value is not None: self.__print__(val.value, level=1) handler.send(flags.whisper, flags.retrieved, packets[1], packets[2], cast(MsgPackable, val.value)) else: handler.send(flags.whisper, flags.retrieved, packets[1], packets[2], None) return True return None
def __handle_retrieve(self, msg, handler): # type: (ChordSocket, Message, BaseConnection) -> Union[bool, None] """This callback is used to deal with data retrieval signals. Its two primary jobs are: - respond with data you possess - if you don't possess it, make a request with your closest peer to that key Args: msg: A :py:class:`~py2p.base.Message` handler: A :py:class:`~py2p.chord.ChordConnection` Returns: Either ``True`` or ``None`` """ packets = msg.packets if packets[0] == flags.retrieve: if sanitize_packet(packets[1]) in hashes: val = self.__lookup( sanitize_packet(packets[1]), b58decode_int(packets[2]), cast(ChordConnection, handler)) if val.value is not None: self.__print__(val.value, level=1) handler.send(flags.whisper, flags.retrieved, packets[1], packets[2], cast(MsgPackable, val.value)) else: handler.send(flags.whisper, flags.retrieved, packets[1], packets[2], None) return True return None
def __init__( self, # type: Any addr, # type: str port, # type: int prot=default_protocol, # type: Protocol out_addr=None, # type: Union[None, Tuple[str, int]] debug_level=0 # type: int ): # type: (...) -> None """Initialize a chord socket""" if not hasattr(self, 'daemon'): self.daemon = 'chord reserved' super(ChordSocket, self).__init__(addr, port, prot, out_addr, debug_level) if self.daemon == 'chord reserved': self.daemon = ChordDaemon(addr, port, self) self.id_10 = b58decode_int(self.id) # type: int self.data = dict(( (method, {}) for method in hashes)) # type: Dict[bytes, Dict[int, MsgPackable]] self.__keys = set() # type: Set[bytes] self.leeching = True # type: bool # self.register_handler(self._handle_peers) self.register_handler(self.__handle_meta) self.register_handler(self.__handle_key) self.register_handler(self.__handle_retrieve) self.register_handler(self.__handle_retrieved) self.register_handler(self.__handle_store) self.register_handler(self.__handle_delta)
def __init__( self, # type: Any addr, # type: str port, # type: int prot=default_protocol, # type: Protocol out_addr=None, # type: Union[None, Tuple[str, int]] debug_level=0 # type: int ): # type: (...) -> None """Initialize a chord socket""" if not hasattr(self, 'daemon'): self.daemon = 'chord reserved' super(ChordSocket, self).__init__(addr, port, prot, out_addr, debug_level) if self.daemon == 'chord reserved': self.daemon = ChordDaemon(addr, port, self) self.id_10 = b58decode_int(self.id) # type: int self.data = dict(( (method, {}) for method in hashes)) # type: Dict[bytes, Dict[int, MsgPackable]] self.__keys = set() # type: Set[bytes] self.leeching = True # type: bool # self.register_handler(self._handle_peers) self.register_handler(self.__handle_meta) self.register_handler(self.__handle_key) self.register_handler(self.__handle_retrieve) self.register_handler(self.__handle_retrieved) self.register_handler(self.__handle_store) self.register_handler(self.__handle_delta)
async def init(): T.LOGGER.debug('') ID_own = None # load key try: c_root_auth = None async with aiosqlite.connect(T.PATH_CREDIT) as db: await db.execute('create table if not exists \ table_own(name nchar({0}) primary key, \ id char({1}) unique, \ pri_key char({2}), \ pub_key_x char({2}), \ pub_key_y char({2}))'. format(G.LEN_NAME, G.LEN_ID, G.LEN_KEY)) async with db.execute('select * from table_own where name=?', (G.NAME_GOD,)) as cursor: async for row in cursor: ID_own = row[T.P_OWN_ID] T.LOGGER.debug(b'select: ' + ID_own) pri_key = base58.b58decode_int(row[T.P_OWN_PRI]) pub_key_x = base58.b58decode_int(row[T.P_OWN_PUB_X]) pub_key_y = base58.b58decode_int(row[T.P_OWN_PUB_Y]) ch_own = Chain(T.FO_CH, ID_own, pri_key, pub_key_x, pub_key_y) # no record, create root card if ID_own is None: ID_own, pri_key, pub_key_x, pub_key_y = Ecc.generate() T.LOGGER.debug(b'create: ' + ID_own) pri_key_b58 = base58.b58encode_int(pri_key) pub_key_x_b58 = base58.b58encode_int(pub_key_x) pub_key_y_b58 = base58.b58encode_int(pub_key_y) await db.execute('insert into table_own values(?,?,?,?,?)', (G.NAME_GOD, ID_own, pri_key_b58, pub_key_x_b58, pub_key_y_b58)) await db.commit() ch_own = Chain(T.FO_CH, ID_own, pri_key, pub_key_x, pub_key_y) c_root_auth = handle.root(ch_own) # own chain if not await ch_own.init(c_root_auth): return False return ch_own except Exception as e: T.LOGGER.warning(e) return False
async def init(self, type_act): T.LOGGER.debug('') # remained coin: -6 self.coin_rest = self.ch_own.coin_rest # if self.ch_own.c_last[G.P_TYPE] == G.CHARGE: # self.coin_rest = (base58.b58decode_int(self.ch_own.c_last[G.P_COIN_REST]) + # base58.b58decode_int(self.ch_own.c_last[G.P_COIN_CHRE])) # elif self.ch_own.c_last[G.P_TYPE] == G.REDEEM: # self.coin_rest = (base58.b58decode_int(self.ch_own.c_last[G.P_COIN_REST]) - # base58.b58decode_int(self.ch_own.c_last[G.P_COIN_CHRE])) # else: # self.coin_rest = base58.b58decode_int(self.ch_own.c_last[G.P_COIN_REST]) # previous mutual chain index: -5 self.i_m = base58.b58decode_int(self.c_rx_list[G.P_I_M]) row = await self.ch_own.get_guide(self.ID_node) if row == None: # for node register in god if type_act == G.CHARGE and self.i_m == 0: self.i_ch_m_pre = 0 else: T.LOGGER.error('guide of ID_node is None') return False else: if type_act == G.CHARGE or type_act == G.REDEEM: p_guide_m = T.P_GUIDE_M_CHRE p_guide_ch = T.P_GUIDE_CH_CHRE elif type_act == G.POST: p_guide_m = T.P_GUIDE_M_POST p_guide_ch = T.P_GUIDE_CH_POST else: T.LOGGER.error('act type is not valid') return False self.i_m_guide = row[p_guide_m] # check i_m if self.i_m == (self.i_m_guide + 1) % G.NUM_I_M: self.i_ch_m_pre = row[p_guide_ch] else: # if self.i_m <= self.i_m_guide and self.i_m >= 0: if self.i_m == self.i_m_guide: # TODO: only consider this case now self.i_ch_fetch = row[p_guide_ch] T.LOGGER.debug( 'mutual index small, turn to TX card already exist') return True else: T.LOGGER.error( 'mutual index not valid: rx_card is {0}; DB guide is {1}'. format(self.i_m, self.i_m_guide)) return False # god chain index: -4 --> chain.i_ch # previous hash: -3 self.hash_pre = self.ch_own.c_last[G.P_HASH] T.LOGGER.debug(self.hash_pre) return True
def verify(cls, content_sign, value_sign, ID): ''' card_list is a list with bytes elements ID is actually pub_key_x + odev ''' sign_list = value_sign.split(b'+') r = base58.b58decode_int(sign_list[0]) s = base58.b58decode_int(sign_list[1]) sign = Signature(r, s) ID_int = base58.b58decode_int(ID) pub_key_x = ID_int // (2**G.NUM_B_ODEV) odev = ID_int % (2**G.NUM_B_ODEV) pub_key_y = cls.pub_key_x2y(pub_key_x, odev) pub = PublicKey(pub_key_x, pub_key_y, secp256k1) return Ecdsa.verify(content_sign, sign, pub)
def preview(request, id_str): try: id_int = base58.b58decode_int(id_str) except ValueError: raise Http404 link = get_object_or_404(Link, id=id_int) return render(request, 'preview.html', { 'link': link, })
def checking(address, sk): if len(sk) != 52: return False k = base58.b58decode_int(sk) k = hex(k)[4:len(hex(k)) - 11] pk = privateKeyToPublicKey(k) com_pk = compressionPk(pk) final_pk = pkHash(com_pk) if address == final_pk: return True else: return False
async def login(cls_App, row_own): T.LOGGER.debug('') ID_own = row_own[T.P_OWN_ID] pri_key = base58.b58decode_int(row_own[T.P_OWN_PRI]) pub_key_x = base58.b58decode_int(row_own[T.P_OWN_PUB_X]) pub_key_y = base58.b58decode_int(row_own[T.P_OWN_PUB_Y]) # own chain cls_App.ch_own = Chain(T.FO_CH, ID_own, pri_key, pub_key_x, pub_key_y) if not await cls_App.ch_own.init(): return False # init DB_credit async with aiosqlite.connect(T.PATH_CREDIT) as db: await db.execute('create table if not exists \ table_restrict(id char({0}) primary key, \ credit integer)'.format(G.LEN_ID)) # await db.commit() # to do: see if needed after create table return True
async def init(self): # coin_rest: -6 if self.ch_own.c_last[G.P_ID_PAY] == self.ID_pay: coin_rest = ( base58.b58decode_int(self.ch_own.c_last[G.P_COIN_REST]) - base58.b58decode_int(self.ch_own.c_last[G.P_COIN_TRADE])) else: coin_rest = ( base58.b58decode_int(self.ch_own.c_last[G.P_COIN_REST]) + base58.b58decode_int(self.ch_own.c_last[G.P_COIN_TRADE])) self.coin_rest = coin_rest # mutual index and previous partner chain index: 5 and -5 row = await self.ch_own.get_guide(self.ID_earn) if row: ID_earn, i_m_pay, i_ch_pay, i_m_earn, i_ch_earn = row i_m_pay_next = base58.b58encode_int( (base58.b58decode_int(i_m_pay) + 1) % G.NUM_I_M) # i_m_earn_next = base58.b58encode_int((base58.b58decode_int(i_m_earn) + 1) % G.NUM_I_M) else: # create DB row when ID doesn't exist, start from 1 await self.ch_own.set_guide(self.ID_earn) i_ch_pay = base58.b58encode_int(0) i_m_pay_next = base58.b58encode_int(1) self.i_ch_pay_pre = i_ch_pay self.i_m_pay = i_m_pay_next # pay chain index: -4 if self.ch_own.i_l == G.NUM_L_BODY - 1: i_f = self.ch_own.i_f + 1 i_l = 0 else: i_f = self.ch_own.i_f i_l = self.ch_own.i_l + 1 self.i_ch = base58.b58encode_int(i_f * G.NUM_L_BODY + i_l) # previous hash: -3 self.hash_pre = self.ch_own.c_last[G.P_HASH]
def update(self, c_last, i_ch_0=None): T.LOGGER.debug('') if i_ch_0 == None: # for non-init if c_last[G.P_I_CH] != base58.b58encode_int(self.i_ch_next): T.LOGGER.error('chain index is not corrent for last card') return False self.i_ch = self.i_ch_next self.i_f = self.i_f_next self.i_l = self.i_l_next if self.i_l == G.NUM_L_BODY -1: self.i_f_next = self.i_f + 1 self.i_l_next = 0 else: self.i_f_next = self.i_f self.i_l_next = self.i_l + 1 self.i_ch_next = self.i_f_next * G.NUM_L_BODY + self.i_l_next self.c_last = c_last if self.c_last[G.P_TYPE] == G.CHARGE: self.coin_rest = (base58.b58decode_int(self.c_last[G.P_COIN_REST]) + base58.b58decode_int(self.c_last[G.P_COIN_CHRE])) elif self.c_last[G.P_TYPE] == G.REDEEM: self.coin_rest = (base58.b58decode_int(self.c_last[G.P_COIN_REST]) - base58.b58decode_int(self.c_last[G.P_COIN_CHRE])) elif self.c_last[G.P_TYPE] == G.PAY: self.coin_rest = (base58.b58decode_int(self.c_last[G.P_COIN_REST]) - base58.b58decode_int(self.c_last[G.P_COIN_TRADE])) elif self.c_last[G.P_TYPE] == G.EARN: self.coin_rest = (base58.b58decode_int(self.c_last[G.P_COIN_REST]) + base58.b58decode_int(self.c_last[G.P_COIN_TRADE])) else: self.coin_rest = base58.b58decode_int(self.c_last[G.P_COIN_REST]) T.LOGGER.debug('update success') return True
def __handle_delta(self, msg, handler): # type: (ChordSocket, Message, BaseConnection) -> Union[bool, None] """This callback is used to deal with delta storage signals. Its primary job is: - update the mapping in a given key Args: msg: A :py:class:`~py2p.base.Message` handler: A :py:class:`~py2p.chord.ChordConnection` Returns: Either ``True`` or ``None`` """ packets = msg.packets if packets[0] == flags.delta: method = packets[1] key = b58decode_int(packets[2]) self.__delta(method, key, packets[3]) return True return None
def __handle_delta(self, msg, handler): # type: (ChordSocket, Message, BaseConnection) -> Union[bool, None] """This callback is used to deal with delta storage signals. Its primary job is: - update the mapping in a given key Args: msg: A :py:class:`~py2p.base.Message` handler: A :py:class:`~py2p.chord.ChordConnection` Returns: Either ``True`` or ``None`` """ packets = msg.packets if packets[0] == flags.delta: method = packets[1] key = b58decode_int(packets[2]) self.__delta(method, key, packets[3]) return True return None
def __handle_store(self, msg, handler): # type: (ChordSocket, Message, BaseConnection) -> Union[bool, None] """This callback is used to deal with data storage signals. Its two primary jobs are: - store data in keys you're responsible for - if you aren't responsible, make a request with your closest peer to that key Args: msg: A :py:class:`~py2p.base.Message` handler: A :py:class:`~py2p.chord.ChordConnection` Returns: Either ``True`` or ``None`` """ packets = msg.packets if packets[0] == flags.store: method = packets[1] key = b58decode_int(packets[2]) self.__store(method, key, packets[3]) return True return None
def __handle_store(self, msg, handler): # type: (ChordSocket, Message, BaseConnection) -> Union[bool, None] """This callback is used to deal with data storage signals. Its two primary jobs are: - store data in keys you're responsible for - if you aren't responsible, make a request with your closest peer to that key Args: msg: A :py:class:`~py2p.base.Message` handler: A :py:class:`~py2p.chord.ChordConnection` Returns: Either ``True`` or ``None`` """ packets = msg.packets if packets[0] == flags.store: method = packets[1] key = b58decode_int(packets[2]) self.__store(method, key, packets[3]) return True return None
def is_next(id): # type: (Union[bytes, bytearray, str]) -> bool return distance(self.id_10, b58decode_int(id)) <= distance( self.id_10, self.next.id_10)
def test_large_integer(): number = 0x111d38e5fc9071ffcd20b4a763cc9ae4f252bb4e48fd66a835e252ada93ff480d6dd43dc62a641155a5 # noqa assert_that(b58decode_int(alphabet), equal_to(number)) assert_that(b58encode_int(number), equal_to(alphabet[1:]))
async def act2god(cls_App, act, hash_content, root=None): T.LOGGER.debug('') # charge to god card c_auth, hash_c = await act.act_god(hash_content) # TX and get RX with God c_rx_god = await tx_rx(cls_App, c_auth, hash_c) if not c_rx_god: T.LOGGER.warning('card act to god fail') return False # check c_rx_content c_auth_list = c_auth.split() if c_rx_god[:G.P_COIN_CHRE] != c_auth_list[:G.P_HASH]: T.LOGGER.error('not the corresponding charge card') return False # TODO: for now only consider the charge root if root and act.type == G.CHARGE: if c_rx_god[G.P_COIN_CHRE] != base58.b58encode_int(G.COIN_CREDIT): T.LOGGER.error('god coin credit is wrong') return False # charge card to broadcast c_auth_node = act.act_group(c_rx_god) T.LOGGER.debug('ready for add to chain and update guide') # add card to chain and update guide if root and act.type == G.CHARGE: # init root card if not await cls_App.ch_own.init(c_auth_node): return False else: if not await cls_App.ch_own.append(c_auth_node): return False if not await cls_App.ch_own.set_guide(cls_App.ch_own.ID_own, act.i_ch): T.LOGGER.error('set guide ID_own fails') return False cls_App.ch_own.update(c_auth_node.split()) if act.type == G.CHARGE or act.type == G.REDEEM: if not await cls_App.ch_own.set_guide(act.ID_god, base58.b58decode_int( c_rx_god[G.P_I_CH]), i_m_2=act.i_m, i_ch_2=act.i_ch): T.LOGGER.error('set guide ID_god fails') return False elif act.type == G.POST: if not await cls_App.ch_own.set_guide(act.ID_god, base58.b58decode_int( c_rx_god[G.P_I_CH]), i_m_1=act.i_m, i_ch_1=act.i_ch): T.LOGGER.error('set guide ID_god fails') return False else: T.LOGGER.error('act type not valid') return False # broadcast to network if not await tx(cls_App, c_auth_node): T.LOGGER.warning('card charge to network fail') return False return True
def base68to10(str): return base58.b58decode_int(str)
import sys from base58 import b58decode_int min = int(sys.argv[1]) max = int(sys.argv[2]) for o in sys.stdin: if int(b58decode_int(o)) >= min and int(b58decode_int(o)) < max: if sys.argv[3] == "16": a = int((65536.0*(int(b58decode_int(o))-min)/(float(max)-float(min)))) p = int(a % 256) q = int(a / 256) sys.stdout.write("%s%s" %(chr(p),chr(q))) if sys.argv[3] == "8": i = int((256.0*(int(b58decode_int(o))-min)/(float(max)-float(min)))) sys.stdout.write("%s" %(chr(i)))
def fromsk2compk(sk): k = base58.b58decode_int(sk) k = hex(k)[4:len(hex(k)) - 11] pk = privateKeyToPublicKey(k) com_pk = compressionPk(pk) return com_pk
def decode_integer(self, data: Union[str, bytes]) -> int: """ :param data: Union[str, bytes] :return: int """ return b58decode_int(data, alphabet=self.characters)
def test_simple_integers(alphabet): for idx, char in enumerate(alphabet): charbytes = bytes([char]) assert_that(b58decode_int(charbytes, alphabet=alphabet), equal_to(idx)) assert_that(b58encode_int(idx, alphabet=alphabet), equal_to(charbytes))
import sys from base58 import b58decode_int from struct import pack for o in sys.stdin: sys.stdout.write("%s" % (pack("I", b58decode_int(o))))
def test_large_integer(): number = 0x111d38e5fc9071ffcd20b4a763cc9ae4f252bb4e48fd66a835e252ada93ff480d6dd43dc62a641155a5 assert_that(b58decode_int(alphabet), equal_to(number)) assert_that(b58encode_int(number), equal_to(alphabet[1:]))
def test_simple_integers(): for idx, char in enumerate(alphabet): assert_that(b58decode_int(char), equal_to(idx)) assert_that(b58encode_int(idx), equal_to(char))
def id_10(self): # type: (ChordConnection) -> int """Returns the nodes ID as an integer""" if self.__id_10 == -1: self.__id_10 = b58decode_int(self.id) return self.__id_10
def test_simple_integers(): for idx, char in enumerate(BITCOIN_ALPHABET): charbytes = bytes([char]) assert_that(b58decode_int(charbytes), equal_to(idx)) assert_that(b58encode_int(idx), equal_to(charbytes))
def base58_to_entry_uuid(b58_s: str) -> str: uuid_as_int = base58.b58decode_int(b58_s) uuid = UUID(int=uuid_as_int) return str(uuid)
def test_simple_integers(): for idx, char in enumerate(BITCOIN_ALPHABET): char = bytes_from_char(char) assert_that(b58decode_int(char), equal_to(idx)) assert_that(b58encode_int(idx), equal_to(char))
import base58 import sys n = 0 s = 0 for g in sys.stdin.read(): if bool(n % 2): l = 2 * base58.b58decode_int(g) if l > 57: l = l - 57 s = s + l else: s = s + base58.b58decode_int(g) n = n + 1 sys.stdout.write(g) sys.stdout.write(str(base58.b58encode_int(s % 58)))
def is_prev(id): # type: (Union[bytes, bytearray, str]) -> bool return distance(b58decode_int(id), self.id_10) <= distance( self.prev.id_10, self.id_10)
def id_10(self): # type: (ChordConnection) -> int """Returns the nodes ID as an integer""" if self.__id_10 == -1: self.__id_10 = b58decode_int(self.id) return self.__id_10
def is_prev(id): # type: (Union[bytes, bytearray, str]) -> bool return distance(b58decode_int(id), self.id_10) <= distance( self.prev.id_10, self.id_10)
def test_simple_integers(): for idx, char in enumerate(alphabet): char = bytes_from_char(char) assert_that(b58decode_int(char), equal_to(idx)) assert_that(b58encode_int(idx), equal_to(char))
def test_large_integer(): number = 0x111d38e5fc9071ffcd20b4a763cc9ae4f252bb4e48fd66a835e252ada93ff480d6dd43dc62a641155a5 # noqa assert_that(b58decode_int(BITCOIN_ALPHABET), equal_to(number)) assert_that(b58encode_int(number), equal_to(BITCOIN_ALPHABET[1:]))
def is_next(id): # type: (Union[bytes, bytearray, str]) -> bool return distance(self.id_10, b58decode_int(id)) <= distance( self.id_10, self.next.id_10)