¿Cómo convertir un número entero a una cadena en cualquier base?

Resuelto Mark Borgerding asked hace 14 años • 36 respuestas

Python permite la creación sencilla de un número entero a partir de una cadena de una base determinada mediante

int(str, base). 

Quiero realizar lo inverso: creación de una cadena a partir de un número entero , es decir, quiero alguna función int2base(num, base), tal que:

int(int2base(x, b), b) == x

El nombre de la función/orden de los argumentos no es importante.

Para cualquier número xy base bque int()acepte.

Esta es una función fácil de escribir: de hecho, es más fácil que describirla en esta pregunta. Sin embargo, siento que me falta algo.

Conozco las funciones bin, oct, hexpero no puedo usarlas por varias razones:

  • Esas funciones no están disponibles en versiones anteriores de Python, con las cuales necesito compatibilidad con (2.2)

  • Quiero una solución general que pueda llamarse de la misma manera para diferentes bases.

  • Quiero permitir bases distintas a 2, 8, 16

Relacionado

  • Función inversa elegante de Python de int (cadena, base)
  • Entero al sistema base-x usando recursividad en Python
  • Conversión de base 62 en Python
  • ¿Cómo convertir un número entero a la cadena más corta segura para URL en Python?
Mark Borgerding avatar Feb 15 '10 23:02 Mark Borgerding
Aceptado

Sorprendentemente, la gente solo daba soluciones que convertían a bases pequeñas (más pequeñas que la longitud del alfabeto inglés). No se intentó dar una solución que convierta a cualquier base arbitraria de 2 al infinito.

Así que aquí tienes una solución súper sencilla:

def numberToBase(n, b):
    if n == 0:
        return [0]
    digits = []
    while n:
        digits.append(int(n % b))
        n //= b
    return digits[::-1]

entonces, si necesitas convertir algún número súper grande a la base 577,

numberToBase(67854 ** 15 - 102, 577), te dará una solución correcta: [4, 473, 131, 96, 431, 285, 524, 486, 28, 23, 16, 82, 292, 538, 149, 25, 41, 483, 100, 517, 131, 28, 0, 435, 197, 264, 455],

Que luego podrás convertir a cualquier base que desees.

  1. En algún momento notarás que a veces no hay una función de biblioteca incorporada para hacer las cosas que deseas, por lo que debes escribir la tuya propia. Si no está de acuerdo, publique su propia solución con una función incorporada que puede convertir un número de base 10 a base 577.
  2. esto se debe a la falta de comprensión de lo que significa un número en alguna base.
  3. Te animo a que pienses un poco por qué la base de tu método funciona solo para n <= 36. Una vez que hayas terminado, será obvio por qué mi función devuelve una lista y tiene la firma que tiene.
Salvador Dali avatar Feb 23 '2015 02:02 Salvador Dali

Si necesita compatibilidad con versiones antiguas de Python, puede usar gmpy (que incluye una función rápida y completamente general de conversión de int a cadena, y puede construirse para versiones tan antiguas; es posible que deba probar versiones anteriores desde el los recientes no han sido probados para versiones venerables de Python y GMP, sólo algunos algo recientes), o, para menor velocidad pero más conveniencia, use código Python – por ejemplo, para Python 2, más simplemente:

import string
digs = string.digits + string.ascii_letters


def int2base(x, base):
    if x < 0:
        sign = -1
    elif x == 0:
        return digs[0]
    else:
        sign = 1

    x *= sign
    digits = []

    while x:
        digits.append(digs[int(x % base)])
        x = int(x / base)

    if sign < 0:
        digits.append('-')

    digits.reverse()

    return ''.join(digits)

Para Python 3, int(x / base)genera resultados incorrectos y debe cambiarse a x // base:

import string
digs = string.digits + string.ascii_letters


def int2base(x, base):
    if x < 0:
        sign = -1
    elif x == 0:
        return digs[0]
    else:
        sign = 1

    x *= sign
    digits = []

    while x:
        digits.append(digs[x % base])
        x = x // base

    if sign < 0:
        digits.append('-')

    digits.reverse()

    return ''.join(digits)
Alex Martelli avatar Feb 15 '2010 16:02 Alex Martelli
"{0:b}".format(100) # bin: 1100100
"{0:x}".format(100) # hex: 64
"{0:o}".format(100) # oct: 144
Rost avatar Sep 05 '2010 19:09 Rost