Number Base Converter — Python source
Convert numbers between binary, octal, decimal and hexadecimal. BigInt-powered, so it handles arbitrarily large values without precision loss.
This is the Python implementation — the same logic the interactive tool runs, in a shareable, citable form.
"""number-base — Arbitrary-precision base conversion.
Language: Python (3.10+).
CosmoDev polyglot showcase port of the ``number-base`` tool, ported from
src/lib/numberBase.ts. Display source — part of CosmoDev's polyglot tool pages.
Python's built-in ``int`` is arbitrary precision, so conversions are exact for
inputs of any length — the same property TypeScript gets from BigInt. Bases
2–36 are supported. Standard library only; no crypto is involved.
"""
DIGITS = "0123456789abcdefghijklmnopqrstuvwxyz"
def _digit_value(ch: str) -> int:
"""Map a lowercase character to its numeric value: 0–9 for '0'–'9', 10–35
for 'a'–'z'. Returns -1 when the character is not a valid digit."""
if "0" <= ch <= "9":
return ord(ch) - 48
if "a" <= ch <= "z":
return ord(ch) - 87
return -1
def parse_bigint(text: str, base: int) -> int | None:
"""Parse ``text`` as an integer written in ``base`` (2–36).
Returns the parsed int, or None when the base is out of range or the input
contains an invalid digit. A leading sign is honored, and a matching radix
prefix (``0x``/``0b``/``0o``) is stripped only when it agrees with ``base``.
"""
if base < 2 or base > 36:
return None
s = text.strip().lower()
negative = False
if s.startswith("-"):
negative = True
s = s[1:]
elif s.startswith("+"):
s = s[1:]
# A 0x/0b/0o prefix is meaningful only for the matching base.
if (base == 16 and s.startswith("0x")) or \
(base == 2 and s.startswith("0b")) or \
(base == 8 and s.startswith("0o")):
s = s[2:]
if not s:
return None
# Horner's method over the digits. Python's int grows as needed, so this
# stays exact no matter how long the input.
result = 0
for ch in s:
d = _digit_value(ch)
if d < 0 or d >= base:
return None
result = result * base + d
return -result if negative else result
def format_bigint(value: int, base: int) -> str:
"""Format ``value`` as a lowercase string in ``base`` (2–36).
Returns the empty string for an out-of-range base; the sign of zero is
never emitted.
"""
if base < 2 or base > 36:
return ""
if value == 0:
return "0"
negative = value < 0
v = -value if negative else value
digits = []
while v > 0:
# divmod returns both quotient and remainder in one step, avoiding a
# second division to recover the digit.
v, rem = divmod(v, base)
digits.append(DIGITS[rem])
# Digits were produced least-significant first; reverse for display.
if negative:
digits.append("-")
return "".join(reversed(digits))
def convert_base(value: str, from_base: int, to_base: int) -> str | None:
"""Parse ``value`` in ``from_base`` and re-emit it in ``to_base``.
Returns None when the input cannot be parsed.
"""
n = parse_bigint(value, from_base)
if n is None:
return None
return format_bigint(n, to_base)
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →