Пример #1
0
def generate_random_bits(n_bits, rand_func=generate_random_bytes):
    """
  Generates the specified number of random bits as a byte string.
  For example::

      f(x) -> y such that
      f(16) ->           1111 1111 1111 1111; bytes_to_integer(y) => 65535L
      f(17) -> 0000 0001 1111 1111 1111 1111; bytes_to_integer(y) => 131071L

  :param n_bits:
      Number of random bits.

      if n is divisible by 8, (n / 8) bytes will be returned.
      if n is not divisible by 8, ((n / 8) + 1) bytes will be returned
      and the prefixed offset-byte will have `(n % 8)` number of random bits,
      (that is, `8 - (n % 8)` high bits will be cleared).

      The range of the numbers is 0 to (2**n)-1 inclusive.
  :param rand_func:
      Random bytes generator function.
  :returns:
      Bytes.
  """
    if not builtins.is_integer(n_bits):
        raise TypeError("unsupported operand type: %r" % type(n_bits).__name__)
    if n_bits <= 0:
        raise ValueError("number of bits must be greater than 0.")
        # Doesn't perform any floating-point operations.
    quotient, remainder = divmod(n_bits, 8)
    random_bytes = rand_func(quotient)
    if remainder:
        offset = ord(rand_func(1)) >> (8 - remainder)
        random_bytes = builtins.byte(offset) + random_bytes
    return random_bytes
Пример #2
0
def generate_random_bits(n_bits, rand_func=generate_random_bytes):
  """
  Generates the specified number of random bits as a byte string.
  For example::

      f(x) -> y such that
      f(16) ->           1111 1111 1111 1111; bytes_to_integer(y) => 65535L
      f(17) -> 0000 0001 1111 1111 1111 1111; bytes_to_integer(y) => 131071L

  :param n_bits:
      Number of random bits.

      if n is divisible by 8, (n / 8) bytes will be returned.
      if n is not divisible by 8, ((n / 8) + 1) bytes will be returned
      and the prefixed offset-byte will have `(n % 8)` number of random bits,
      (that is, `8 - (n % 8)` high bits will be cleared).

      The range of the numbers is 0 to (2**n)-1 inclusive.
  :param rand_func:
      Random bytes generator function.
  :returns:
      Bytes.
  """
  if not builtins.is_integer(n_bits):
    raise TypeError("unsupported operand type: %r" % type(n_bits).__name__)
  if n_bits <= 0:
    raise ValueError("number of bits must be greater than 0.")
    # Doesn't perform any floating-point operations.
  quotient, remainder = divmod(n_bits, 8)
  random_bytes = rand_func(quotient)
  if remainder:
    offset = ord(rand_func(1)) >> (8 - remainder)
    random_bytes = builtins.byte(offset) + random_bytes
  return random_bytes
Пример #3
0
def uint_to_bytes_simple(num):
    """Simple uint to bytes converter."""
    assert num >= 0
    if num == 0:
        return ZERO_BYTE
    byte_array = []
    while num:
        byte_array.append(builtins.byte(num & 0xff))
        num >>= 8
    return EMPTY_BYTE.join(reversed(byte_array))
Пример #4
0
def uint_to_bytes_simple(num):
  """Simple uint to bytes converter."""
  assert num >= 0
  if num == 0:
    return ZERO_BYTE
  byte_array = []
  while num:
    byte_array.append(builtins.byte(num & 0xff))
    num >>= 8
  return EMPTY_BYTE.join(reversed(byte_array))
Пример #5
0
def b58decode_bitcoin(encoded, length=None):
    """ decode v into a string of len bytes
  """
    long_value = 0
    for i, c in enumerate(encoded[::-1]):
        long_value += ALPHABET.find(_chr(c)) * (BASE**i)

    result = EMPTY_BYTE
    while long_value >= 256:
        div, mod = divmod(long_value, 256)
        result = builtins.byte(mod) + result
        long_value = div
    result = builtins.byte(long_value) + result

    nPad = 0
    for c in encoded:
        if c == ALPHABET[0]: nPad += 1
        else: break

    result = builtins.byte(0) * nPad + result
    if length is not None and len(result) != length:
        return None

    return result
Пример #6
0
def b58decode_bitcoin(encoded, length=None):
  """ decode v into a string of len bytes
  """
  long_value = 0
  for i, c in enumerate(encoded[::-1]):
    long_value += ALPHABET.find(_chr(c)) * (BASE ** i)

  result = EMPTY_BYTE
  while long_value >= 256:
    div, mod = divmod(long_value, 256)
    result = byte(mod) + result
    long_value = div
  result = byte(long_value) + result

  nPad = 0
  for c in encoded:
    if c == ALPHABET[0]: nPad += 1
    else: break

  result = byte(0) * nPad + result
  if length is not None and len(result) != length:
    return None

  return result
Пример #7
0
def uint_to_bytes_naive(number, block_size=0):
    """
  Naive slow and accurate implementation. Base for all our tests.

  Converts a number to a string of bytes.

  :param number: the number to convert
  :param block_size: the number of bytes to output. If the number encoded to
      bytes is less than this, the block will be zero-padded. When not given,
      the returned block is not padded.

  :raises:
      ``OverflowError`` when block_size is given and the number takes up more
      bytes than fit into the block.
  """
    if number < 0:
        raise ValueError("Negative numbers cannot be used: %d" % number)

    # Do some bounds checking
    needed_bytes = builtins.integer_byte_length(number)
    if block_size > 0:
        if needed_bytes > block_size:
            raise OverflowError("Needed %i bytes for number, but block size "
                                "is %i" % (needed_bytes, block_size))

    # Convert the number to bytes.
    if number == 0:
        raw_bytes = [ZERO_BYTE]
    else:
        raw_bytes = []
        num = number
        while num > 0:
            raw_bytes.insert(0, builtins.byte(num & 0xFF))
            num >>= 8

    # Pad with zeroes to fill the block
    if block_size > 0:
        padding_size = (block_size - needed_bytes)
        if number == 0:
            padding_size -= 1
        padding = ZERO_BYTE * padding_size
    else:
        padding = EMPTY_BYTE
    return padding + EMPTY_BYTE.join(raw_bytes)
Пример #8
0
def uint_to_bytes_naive(number, block_size=0):
  """
  Naive slow and accurate implementation. Base for all our tests.

  Converts a number to a string of bytes.

  :param number: the number to convert
  :param block_size: the number of bytes to output. If the number encoded to
      bytes is less than this, the block will be zero-padded. When not given,
      the returned block is not padded.

  :raises:
      ``OverflowError`` when block_size is given and the number takes up more
      bytes than fit into the block.
  """
  if number < 0:
    raise ValueError("Negative numbers cannot be used: %d" % number)

  # Do some bounds checking
  needed_bytes = builtins.integer_byte_length(number)
  if block_size > 0:
    if needed_bytes > block_size:
      raise OverflowError("Needed %i bytes for number, but block size "
                          "is %i" % (needed_bytes, block_size))

  # Convert the number to bytes.
  if number == 0:
    raw_bytes = [ZERO_BYTE]
  else:
    raw_bytes = []
    num = number
    while num > 0:
      raw_bytes.insert(0, builtins.byte(num & 0xFF))
      num >>= 8

  # Pad with zeroes to fill the block
  if block_size > 0:
    padding_size = (block_size - needed_bytes)
    if number == 0:
      padding_size -= 1
    padding = ZERO_BYTE * padding_size
  else:
    padding = EMPTY_BYTE
  return padding + EMPTY_BYTE.join(raw_bytes)
Пример #9
0
def _b85decode_chunks(encoded, base85_bytes, base85_ords):
  """
  Base-85 decodes.

  :param encoded:
      Encoded ASCII string.
  :param base85_bytes:
      Character set to use.
  :param base85_ords:
      A function to convert a base85 character to its ordinal
      value. You should not need to use this.
  :returns:
      Base-85-decoded raw bytes.
  """
  # We want 5-tuple chunks, so pad with as many base85_ord == 84 characters
  # as required to satisfy the length.
  length = len(encoded)
  num_uint32s, remainder = divmod(length, 5)
  if remainder:
    padding_byte = byte(base85_bytes[84]) # 'u' (ASCII85); '~' (RFC1924)
    padding_size = 5 - remainder
    encoded += padding_byte * padding_size
    num_uint32s += 1
    length += padding_size
  else:
    padding_size = 0

  #uint32s = [0] * num_uint32s
  uint32s = array('I', [0] * num_uint32s)
  j = 0
  chunk = EMPTY_BYTE
  try:
    for i in range(0, length, 5):
      chunk = encoded[i:i + 5]
      #        uint32_value = 0
      #        for char in chunk:
      #            uint32_value = uint32_value * 85 + _base85_ords[char]
      #        Above loop unrolled:
      uint32_value = ((((base85_ords[chunk[0]] *
                         85 + base85_ords[chunk[1]]) *
                        85 + base85_ords[chunk[2]]) *
                       85 + base85_ords[chunk[3]]) *
                      85 + base85_ords[chunk[4]])
      # I've left this approach in here to warn you to NOT use it.
      # This results in a massive amount of calls to byte_ord inside
      # tight loops.
      #        uint32_value = ((((base85_ords[byte_ord(chunk[0])] *
      #                        85 + base85_ords[byte_ord(chunk[1])]) *
      #                        85 + base85_ords[byte_ord(chunk[2])]) *
      #                        85 + base85_ords[byte_ord(chunk[3])]) *
      #                        85 + base85_ords[byte_ord(chunk[4])])
      # Groups of characters that decode to a value greater than 2**32 − 1
      # (encoded as "s8W-!") will cause a decoding error. Bad byte?
      if uint32_value > UINT32_MAX: # 2**32 - 1
        raise OverflowError("Cannot decode chunk `%r`" % chunk)

      uint32s[j] = uint32_value
      j += 1
  except KeyError:
    raise OverflowError("Cannot decode chunk `%r`" % chunk)

  raw_bytes = pack(">" + "L" * num_uint32s, *uint32s)
  if padding_size:
    # Only as much padding added before decoding is removed after decoding.
    raw_bytes = raw_bytes[:-padding_size]
  return raw_bytes
Пример #10
0
# I've left this approach in here to warn you to NOT use it.
# This results in a massive amount of calls to byte_ord inside
# tight loops. Don't use the array. Use the dictionary. It
# removes the need to convert to ords at runtime.
#RFC1924_ORDS = array('B', [255] * 128)
#for ordinal, _byte in enumerate(RFC1924_BYTES):
#    RFC1924_ORDS[_byte] = ordinal

if HAVE_PYTHON3: # pragma: no cover
  # Python 3 bytes when indexed yield integers, not single-character
  # byte strings.
  ASCII85_ORDS = dict((x, x - 33) for x in ASCII85_BYTES)
  RFC1924_ORDS = dict((x, i) for i, x in enumerate(RFC1924_BYTES))
else:
  # Indexing into Python 2 bytes yields single-character byte strings.
  ASCII85_ORDS = dict((byte(x), x - 33) for x in ASCII85_BYTES)
  RFC1924_ORDS = dict((byte(x), i) for i, x in enumerate(RFC1924_BYTES))


# Pre-computed powers (array index) of 85 used to unroll encoding loops
# Therefore, 85**i is equivalent to POW_85[i] for index 0 through 19
# (inclusive).
#
#POW_85 = tuple(85**power for power in range(20))
POW_85 = (
  1,
  85,
  7225,
  614125,
  52200625,
  4437053125,
Пример #11
0
from mom import builtins
from mom import string
from mom.codec import _base


__author__ = "[email protected] (Yesudeep Mangalapilly)"


EMPTY_BYTE = _compat.EMPTY_BYTE

# Follows ASCII order.
ASCII36_BYTES = (string.DIGITS +
                 string.ASCII_UPPERCASE).encode("ascii")
# Therefore, b"1" represents b"\0".
if _compat.HAVE_PYTHON3:
  ASCII36_BYTES = tuple(builtins.byte(x) for x in ASCII36_BYTES)


def b36encode(raw_bytes, base_bytes=ASCII36_BYTES, _padding=True):
  """
  Base-36 encodes a sequence of raw bytes. Zero-byte sequences are
  preserved by default.

  :param raw_bytes:
      Raw bytes to encode.
  :param base_bytes:
      The character set to use. Defaults to ``ASCII36_BYTES``
      that uses natural ASCII order.
  :param _padding:
      (Internal) ``True`` (default) to include prefixed zero-byte sequence
      padding converted to appropriate representation.
Пример #12
0
except ImportError: #pragma: no cover
  psyco = None
# pylint: enable-msg=R0801


from mom import string
from mom._compat import HAVE_PYTHON3, EMPTY_BYTE
from mom.builtins import byte
from mom.codec._base import base_encode, uint_to_base256

# Follows ASCII order.
ASCII36_BYTES = (string.DIGITS +
                 string.ASCII_UPPERCASE).encode("ascii")
# Therefore, b'1' represents b'\0'.
if HAVE_PYTHON3:
  ASCII36_BYTES = tuple(byte(x) for x in ASCII36_BYTES)


def b36encode(raw_bytes, base_bytes=ASCII36_BYTES, _padding=True):
  """
  Base-36 encodes a sequence of raw bytes. Zero-byte sequences are
  preserved by default.

  :param raw_bytes:
      Raw bytes to encode.
  :param base_bytes:
      The character set to use. Defaults to ``ASCII36_BYTES``
      that uses natural ASCII order.
  :param _padding:
      (Internal) ``True`` (default) to include prefixed zero-byte sequence
      padding converted to appropriate representation.
Пример #13
0
 def _chr(c):
   return builtins.byte(c)
Пример #14
0
 def test_byte(self):
   for i in range(256):
     byt = byte(i)
     self.assertTrue(is_bytes(byt))
     self.assertEqual(ord(byt), i)
Пример #15
0
ASCII58_ORDS = dict((x, i) for i, x in enumerate(ASCII58_BYTES))


# Really, I don't understand why people use the non-ASCII order,
# but if you really like it that much, go ahead. Be my guest. Here
# is what you will need:
#
# Does not follow ASCII order.
ALT58_BYTES = ("123456789"
               "abcdefghijkmnopqrstuvwxyz"
               "ABCDEFGHJKLMNPQRSTUVWXYZ").encode("ascii")
# Therefore, b"1" represents b"\0".
ALT58_ORDS = dict((x, i) for i, x in enumerate(ALT58_BYTES))

if _compat.HAVE_PYTHON3:
  ASCII58_BYTES = tuple(builtins.byte(x) for x in ASCII58_BYTES)
  ALT58_BYTES = tuple(builtins.byte(x) for x in ALT58_BYTES)

# If you're going to make people type stuff longer than this length
# I don't know what to tell you. Beyond this length powers
# are computed, so be careful if you care about computation speed.
# I think this is a VERY generous range. Decoding bytes fewer than 512
# will use this pre-computed lookup table, and hence, be faster.
POW_58 = tuple(58 ** power for power in builtins.range(512))


def b58encode(raw_bytes,
              base_bytes=ASCII58_BYTES, _padding=True):
  """
  Base58 encodes a sequence of raw bytes. Zero-byte sequences are
  preserved by default.
Пример #16
0
# I've left this approach in here to warn you to NOT use it.
# This results in a massive amount of calls to byte_ord inside
# tight loops. Don't use the array. Use the dictionary. It
# removes the need to convert to ords at runtime.
# RFC1924_ORDS = array.array("B", [255] * 128)
# for ordinal, _byte in enumerate(RFC1924_BYTES):
#   RFC1924_ORDS[_byte] = ordinal

if _compat.HAVE_PYTHON3:  # pragma: no cover
  # Python 3 bytes when indexed yield integers, not single-character
  # byte strings.
  ASCII85_ORDS = dict((x, x - 33) for x in ASCII85_BYTES)
  RFC1924_ORDS = dict((x, i) for i, x in enumerate(RFC1924_BYTES))
else:
  # Indexing into Python 2 bytes yields single-character byte strings.
  ASCII85_ORDS = dict((builtins.byte(x), x - 33) for x in ASCII85_BYTES)
  RFC1924_ORDS = dict((builtins.byte(x), i)
                      for i, x in enumerate(RFC1924_BYTES))


# Pre-computed powers (array index) of 85 used to unroll encoding loops
# Therefore, 85**i is equivalent to POW_85[i] for index 0 through 19
# (inclusive).
#
#POW_85 = tuple(85**power for power in builtins.range(20))
POW_85 = (
    1,
    85,
    7225,
    614125,
    52200625,
Пример #17
0
# Therefore, b"1" represents b"\0".
ASCII58_ORDS = dict((x, i) for i, x in enumerate(ASCII58_BYTES))

# Really, I don't understand why people use the non-ASCII order,
# but if you really like it that much, go ahead. Be my guest. Here
# is what you will need:
#
# Does not follow ASCII order.
ALT58_BYTES = ("123456789"
               "abcdefghijkmnopqrstuvwxyz"
               "ABCDEFGHJKLMNPQRSTUVWXYZ").encode("ascii")
# Therefore, b"1" represents b"\0".
ALT58_ORDS = dict((x, i) for i, x in enumerate(ALT58_BYTES))

if _compat.HAVE_PYTHON3:
    ASCII58_BYTES = tuple(builtins.byte(x) for x in ASCII58_BYTES)
    ALT58_BYTES = tuple(builtins.byte(x) for x in ALT58_BYTES)

# If you're going to make people type stuff longer than this length
# I don't know what to tell you. Beyond this length powers
# are computed, so be careful if you care about computation speed.
# I think this is a VERY generous range. Decoding bytes fewer than 512
# will use this pre-computed lookup table, and hence, be faster.
POW_58 = tuple(58**power for power in builtins.range(512))


def b58encode(raw_bytes, base_bytes=ASCII58_BYTES, _padding=True):
    """
  Base58 encodes a sequence of raw bytes. Zero-byte sequences are
  preserved by default.
Пример #18
0
ASCII62_ORDS = dict((x, i) for i, x in enumerate(ASCII62_BYTES))


# Really, I don't understand why people use the non-ASCII order,
# but if you really like it that much, go ahead. Be my guest. Here
# is what you will need:
#
# Does not follow ASCII order.
ALT62_BYTES = (string.DIGITS +
               string.ASCII_LOWERCASE +
               string.ASCII_UPPERCASE).encode("ascii")
# Therefore, b'0' represents b'\0'.
ALT62_ORDS = dict((x, i) for i, x in enumerate(ALT62_BYTES))

if HAVE_PYTHON3:
  ASCII62_BYTES = tuple(byte(x) for x in ASCII62_BYTES)
  ALT62_BYTES = tuple(byte(x) for x in ALT62_BYTES)

# If you're going to make people type stuff longer than this length
# I don't know what to tell you. Beyond this length powers
# are computed, so be careful if you care about computation speed.
# I think this is a VERY generous range. Decoding bytes fewer than 512
# will use this pre-computed lookup table, and hence, be faster.
POW_62 = tuple(62 ** power for power in range(512))


def b62encode(raw_bytes,
              base_bytes=ASCII62_BYTES,
              _padding=True):
  """
  Base62 encodes a sequence of raw bytes. Zero-byte sequences are
Пример #19
0
                 string.ASCII_LOWERCASE).encode("ascii")
# Therefore, b"0" represents b"\0".
ASCII62_ORDS = dict((x, i) for i, x in enumerate(ASCII62_BYTES))

# Really, I don't understand why people use the non-ASCII order,
# but if you really like it that much, go ahead. Be my guest. Here
# is what you will need:
#
# Does not follow ASCII order.
ALT62_BYTES = (string.DIGITS + string.ASCII_LOWERCASE +
               string.ASCII_UPPERCASE).encode("ascii")
# Therefore, b"0" represents b"\0".
ALT62_ORDS = dict((x, i) for i, x in enumerate(ALT62_BYTES))

if _compat.HAVE_PYTHON3:
    ASCII62_BYTES = tuple(builtins.byte(x) for x in ASCII62_BYTES)
    ALT62_BYTES = tuple(builtins.byte(x) for x in ALT62_BYTES)

# If you're going to make people type stuff longer than this length
# I don't know what to tell you. Beyond this length powers
# are computed, so be careful if you care about computation speed.
# I think this is a VERY generous range. Decoding bytes fewer than 512
# will use this pre-computed lookup table, and hence, be faster.
POW_62 = tuple(62**power for power in range(512))


def b62encode(raw_bytes, base_bytes=ASCII62_BYTES, _padding=True):
    """
  Base62 encodes a sequence of raw bytes. Zero-byte sequences are
  preserved by default.
Пример #20
0
def _b85decode_chunks(encoded, base85_bytes, base85_ords):
  """Base-85 decodes.

  :param encoded:
      Encoded ASCII string.
  :param base85_bytes:
      Character set to use.
  :param base85_ords:
      A function to convert a base85 character to its ordinal
      value. You should not need to use this.
  :returns:
      Base-85-decoded raw bytes.
  """
  # We want 5-tuple chunks, so pad with as many base85_ord == 84 characters
  # as required to satisfy the length.
  length = len(encoded)
  num_uint32s, remainder = divmod(length, 5)
  if remainder:
    padding_byte = builtins.byte(base85_bytes[84])  # "u"(ASCII85);"~"(RFC1924)
    padding_size = 5 - remainder
    encoded += padding_byte * padding_size
    num_uint32s += 1
    length += padding_size
  else:
    padding_size = 0

  #uint32s = [0] * num_uint32s
  uint32s = array.array("I", [0] * num_uint32s)
  j = 0
  chunk = EMPTY_BYTE
  try:
    for i in builtins.range(0, length, 5):
      chunk = encoded[i:i + 5]
      #        uint32_value = 0
      #        for char in chunk:
      #            uint32_value = uint32_value * 85 + _base85_ords[char]
      #        Above loop unrolled:
      uint32_value = ((((base85_ords[chunk[0]] *
                         85 + base85_ords[chunk[1]]) *
                        85 + base85_ords[chunk[2]]) *
                       85 + base85_ords[chunk[3]]) *
                      85 + base85_ords[chunk[4]])
      # I've left this approach in here to warn you to NOT use it.
      # This results in a massive amount of calls to byte_ord inside
      # tight loops.
      #        uint32_value = ((((base85_ords[byte_ord(chunk[0])] *
      #                        85 + base85_ords[byte_ord(chunk[1])]) *
      #                        85 + base85_ords[byte_ord(chunk[2])]) *
      #                        85 + base85_ords[byte_ord(chunk[3])]) *
      #                        85 + base85_ords[byte_ord(chunk[4])])
      # Groups of characters that decode to a value greater than 2**32 − 1
      # (encoded as "s8W-!") will cause a decoding error. Bad byte?
      if uint32_value > UINT32_MAX:  # 2**32 - 1
        raise OverflowError("Cannot decode chunk `%r`" % chunk)

      uint32s[j] = uint32_value
      j += 1
  except KeyError:
    raise OverflowError("Cannot decode chunk `%r`" % chunk)

  raw_bytes = struct.pack(">" + "L" * num_uint32s, *uint32s)
  if padding_size:
    # Only as much padding added before decoding is removed after decoding.
    raw_bytes = raw_bytes[:-padding_size]
  return raw_bytes
Пример #21
0
 def _chr(c):
     return builtins.byte(c)
Пример #22
0
ASCII62_ORDS = dict((x, i) for i, x in enumerate(ASCII62_BYTES))


# Really, I don't understand why people use the non-ASCII order,
# but if you really like it that much, go ahead. Be my guest. Here
# is what you will need:
#
# Does not follow ASCII order.
ALT62_BYTES = (string.DIGITS +
               string.ASCII_LOWERCASE +
               string.ASCII_UPPERCASE).encode("ascii")
# Therefore, b"0" represents b"\0".
ALT62_ORDS = dict((x, i) for i, x in enumerate(ALT62_BYTES))

if _compat.HAVE_PYTHON3:
  ASCII62_BYTES = tuple(builtins.byte(x) for x in ASCII62_BYTES)
  ALT62_BYTES = tuple(builtins.byte(x) for x in ALT62_BYTES)

# If you're going to make people type stuff longer than this length
# I don't know what to tell you. Beyond this length powers
# are computed, so be careful if you care about computation speed.
# I think this is a VERY generous range. Decoding bytes fewer than 512
# will use this pre-computed lookup table, and hence, be faster.
POW_62 = tuple(62 ** power for power in range(512))


def b62encode(raw_bytes,
              base_bytes=ASCII62_BYTES,
              _padding=True):
  """
  Base62 encodes a sequence of raw bytes. Zero-byte sequences are
Пример #23
0
 def _chr(c):
   return byte(c)