Как увеличить alphanumeri c число в python? - PullRequest
4 голосов
/ 03 февраля 2020

Я создаю пароль из 16 буквенно-цифровых символов c символов, где я генерирую начиная с 4 цифр с A001, A002, A003 до A999. Как только он дойдет до A999, алфавит автоматически увеличится до B, а цифры снова начнутся с 001. И тот же процесс будет go до Z999. Как только серия AZ закончится, она начнется с AA01 и так далее. Как это сделать в python? Поскольку я новичок в python, я попробовал это сам, а также попробовал несколько примеров, но я не могу сделать приращение символов. Любые идеи или мысли будут с благодарностью.

Большое спасибо

rec=0
new_list16 = []
def autoIncrement():
    global rec
    first = 'A'
    i = chr(ord(first))
    new_list16.append(i)

    while True:
        pStart = 1 #adjust start value, if req'd 
        pInterval = 1 #adjust interval value, if req'd
        if (rec == 0):
            rec += pStart
        else:
            rec = rec + pInterval
        return str(rec).zfill(3)
#print(autoIncrement())
new_list16.append(autoIncrement())

print(*new_list16, sep = '')

Ответы [ 5 ]

2 голосов
/ 03 февраля 2020

Переход от A999 к B001 вместо B000 действительно немного запутывает, но вы все равно можете использовать this для части AZ и простую операцию по модулю для чисел.

def excel_format(num):
    # see https://stackoverflow.com/a/182924/1639625
    res = ""
    while num:
        mod = (num - 1) % 26
        res = chr(65 + mod) + res
        num = (num - mod) // 26
    return res

def full_format(num, d=3):
    chars = num // (10**d-1) + 1 # this becomes   A..ZZZ
    digit = num %  (10**d-1) + 1 # this becomes 001..999
    return excel_format(chars) + "{:0{}d}".format(digit, d)

for i in range(10000):
    print(i, full_format(i, d=2))

Количество цифр в части цифр c контролируется необязательным параметром d. Я буду использовать 2 для демонстрации, но 3 работает так же хорошо.

0 A01
...
98 A99
99 B01
...
2573 Z99
2574 AA01
...
9998 CW99
9999 CX01
1 голос
/ 03 февраля 2020

Это не совсем то, о чем вы просите, но если вы хотите использовать 4-символьные "последовательные" строки, позвольте мне предложить гораздо более простой подход. Почему бы просто не использовать базовые 36 номеров? То есть, ваши числа go из 0, 1, 2, ... A, B, C, ... Z, 10, 11, 12, ... 1Z, ... Затем для преобразования одной из базовых 36 строк в int это просто:

n = int('12AV', 36)

И для преобразования int в базовую строку n:

def baseN(num, base, numerals="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
      return ((num == 0) and numerals[0]) or (baseN(num // base, base, numerals).lstrip(numerals[0]) + numerals[num % base])

Собираем все вместе:

n = int('12AV', 36)
s = baseN(n + 1, 36)
print(s)

Отпечатки:

12AW

Вы можете, конечно, начать с 'A001', если вам нужно. Затем вы будете go до A00Z после 35 итераций. В итоге вы получите те же числа, что и в исходном методе, но в другом порядке.

1 голос
/ 03 февраля 2020
def auto_increment(number):
    if number == 'ZZZZ':
        return 'ZZZZ'

    digits = "".join([i for i in number if i.isdigit()])
    chars = "".join([i for i in number if not i.isdigit()])
    if int(digits) == int('9' * len(digits)):
        digits = "000"
        new_char = [ord(i) for i in chars]
        if new_char[-1] % ord('Z') == 0:
            new_char = "".join([chr(i) for i in new_char]) + 'A'
        else:
            new_char[-1] = new_char[-1] + 1
            new_char = "".join([chr(i) for i in new_char])
    else:
        new_char = chars

    new_digit = int(digits) + 1
    l = len(new_char) 
    ll = len(str(new_digit))
    new_digit = (("0" * (3-ll)) + str(new_digit))[(l-1):]
    return f"{new_char}{new_digit}"

Эта функция возвращает вам следующий номер, заданный любым номером. например: A999 вернет AB01.

теперь вы можете просто использовать эту функцию в al oop.

1 голос
/ 03 февраля 2020

Это, вероятно, нужно больше тестировать и подвергать рефакторингу, но вот вам начало:

def leadingZeros(number, digits):
    numberString = str(number)
    for digit in range(1, digits):
        if number < 10**digit:
            numberString = '0' + numberString
    return numberString


def autoIncrement(oldNumber):
    order = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!'
    lastDigitOrder = order.find(oldNumber[3])
    newNumber = ''
    if order.find(oldNumber[1]) <= 9:
        # 3 digit number
        number = int(oldNumber[1:]) + 1
        letter = oldNumber[0]
        if 1000 == number:
            letterOrder = order.find(oldNumber[0])
            letter = order[letterOrder + 1]
        newNumber = letter + leadingZeros(number % 1000, 3)
    elif order.find(oldNumber[2]) <= 9:
        # 2 digit number
        number = int(oldNumber[2:]) + 1
        letters = oldNumber[0:2]
        if 100 == number:
            letterOrder = order.find(oldNumber[1])
            letter = order[letterOrder + 1]
            letters = oldNumber[0] + letter
        newNumber = letters + leadingZeros(number % 100, 2)
    elif order.find(oldNumber[3]) <= 9:
        # 1 digit number
        number = int(oldNumber[3]) + 1
        letters = oldNumber[0:3]
        if 10 == number:
            letterOrder = order.find(oldNumber[2])
            letter = order[letterOrder + 1]
            letters = oldNumber[0:2] + letter
        newNumber = letters + leadingZeros(number % 10, 1)
    else:
        # just letters
        print(oldNumber)
        letterOrder = order.find(oldNumber[3])
        letter = order[letterOrder + 1]
        newNumber = oldNumber[0:3] + letter

    # if one of the digits has gone past Z then we need to update the letters
    if '!' == newNumber[3]:
        # past Z in 4th digit
        letterOrder = order.find(oldNumber[2])
        newNumber = newNumber[0:2] + order[letterOrder + 1] + 'A'
    if '!' == newNumber[2]:
        # past Z in 3rd digit
        letterOrder = order.find(oldNumber[1])
        newNumber = newNumber[0:1] + order[letterOrder + 1] + 'A' + newNumber[3]
    if '!' == newNumber[1]:
        # past Z in 2nd digit
        letterOrder = order.find(oldNumber[0])
        newNumber = order[letterOrder + 1] + 'A' + newNumber[2:]

    return newNumber


print(autoIncrement('A999'))
print(autoIncrement('AA99'))
print(autoIncrement('AAA9'))
print(autoIncrement('AAAA'))
print(autoIncrement('AZZ9'))
0 голосов
/ 12 февраля 2020

Спасибо за предоставленные вами решения. Но я попробовал что-то именно то, что я хочу для моего вопроса. Пожалуйста, проверьте это и оставьте свои комментарии.

def full_format(i):
    # limit of first range is 26 letters (A-Z) times 999 numbers (001-999)
    if i < 26 * 999:
        c,n = divmod(i,999)   # quotient c is index of letter 0-25, remainder n is 0-998
        c = chr(ord('A') + c) # compute letter
        n += 1
        return f'{c}{n:03}'
    # After first range, second range is 26 letters times 26 letters * 99 numbers (01-99)
    elif i < 26*999 + 26*26*99:
        i -= 26*999               # remove first range offset
        cc,n = divmod(i,99)       # remainder n is 0-98, use quotient cc to compute two letters
        c1,c2 = divmod(cc,26)     # c1 is index of first letter, c2 is index of second letter
        c1 = chr(ord('A') + c1)   # compute first letter
        c2 = chr(ord('A') + c2)   # compute second letter
        n += 1
        return f'{c1}{c2}{n:02}'
    else:
        raise OverflowError(f'limit is {26*999+26*26*99}')

for i in range(92880, 92898):
    print(full_format(i))
...