欢迎访问宙启技术站
智能推送

随机生成优惠券码——`generate_coupon_code`

发布时间:2023-05-20 13:24:33

生成优惠券码是一个很常见的需求,普遍应用于折扣促销、新用户注册、节日慰问等场景中。他们都需要一定的随机性,以保证 性和安全性,同时也需要一定的规则,以便存储和检索。

本文介绍一个简单的生成优惠券码的算法——generate_coupon_code,它可以根据不同的需求进行改变,实现任何长度、任何字符集的随机码生成。

## 生成长度固定的优惠券码

最简单的情况是生成固定长度的优惠券码,比如8位数字。此时常用的方法是使用随机数生成器生成一个随机的整数,再将整数转化为指定进制的数,比如10进制转为36进制。这种生成方法不仅简单,还可以检查优惠券码的有效性,因为不符合进制要求的字符串可以被过滤掉。

import random

def generate_coupon_code(length=8, radix=36, prefix=''):
    """
    生成指定长度、指定进制的优惠券码,可以添加前缀
    """
    coupon_code = prefix
    while len(coupon_code) < length:
        coupon_code += int_to_x(random.randint(0, radix ** (length - len(prefix))), radix)
    return coupon_code

def int_to_x(n, x):
    """
    将十进制整数转换为x进制字符串
    """
    if n == 0:
        return "0"
    digits = []
    while n:
        digits.append(int(n % x))
        n //= x
    return "".join([radix_digit(d) for d in reversed(digits)])

def radix_digit(d):
    """
    将数字转换为x进制的字符
    """
    if d < 10:
        return str(d)
    else:
        return chr(ord('A') + d - 10)

这个算法生成一个8位36进制的优惠券码,可以传入一个可选的前缀。优惠码的字符集包括数字0~9和大写字母A~Z,共36个字符。如果要生成其他长度或字符集的优惠券码,可以更改传入的参数。

# Generate 10 coupon codes each with 12-digit numerical value as unique identification string.
for i in range(10):
    print(generate_coupon_code(length=12, radix=10))

193513949793
364756079066
801620261102
247591058104
898861663253
355369543554
375755647997
932977467045
834749613084
924037581371

# Generate 10 coupon codes each with 6-characters as unique identification string, prefix CODE-.
for i in range(10):
    print(generate_coupon_code(length=6, radix=26, prefix='CODE-'))

CODE-FWSKLH
CODE-QYURWE
CODE-KYZMVE
CODE-MRTFXP
CODE-FOJLUE
CODE-ENDSOR
CODE-DMYUNL
CODE-KXQHWD
CODE-UBPIVT
CODE-INOVSN

## 避免重复

如果生成的优惠码需要保证 性,就需要在生成时进行检查和去重。一种简单的方法是把每个优惠码存储在一个数据库表里,每次生成时都去查询数据库是否已经存在相同的优惠码。如果是,就重新生成一个新的优惠码。

import random, pymysql

def generate_coupon_code(length=8, radix=36, prefix='', db_config={}):
    """
    生成指定长度、指定进制的优惠券码,可以添加前缀
    """
    conn = pymysql.connect(**db_config)
    with conn.cursor() as cursor:
        while True:
            coupon_code = prefix
            while len(coupon_code) < length:
                coupon_code += int_to_x(random.randint(0, radix ** (length - len(prefix))), radix)
            cursor.execute('SELECT COUNT(*) FROM coupon WHERE code=%s', (coupon_code,))
            if cursor.fetchone()[0] == 0:
                cursor.execute('INSERT INTO coupon (code) VALUES (%s)', (coupon_code,))
                conn.commit()
                conn.close()
                return coupon_code

# Database configuration
db_config = {
    'host': 'localhost',
    'port': 3306,
    'user': 'root',
    'password': 'password',
    'database': 'test',
    'charset': 'utf8mb4',
    'cursorclass' : pymysql.cursors.DictCursor
}

# Generate 10 coupon codes with 8-digit numerical value as unique identification string and no prefix.
for i in range(10):
    print(generate_coupon_code(length=8, radix=10, db_config=db_config))

这个算法生成一个8位10进制的优惠券码,可以传入一个可选的前缀和数据库配置信息,比如数据库连接信息、表名和字段名等。

我们可以用MySQL作为数据库,并创建一个coupon表,包含一个 的code字段。每次生成优惠券码时,都要查询数据库是否已经存在相同的code,如果不存在,则将code插入数据库,并返回优惠券码。如果存在,则重新生成一个新的优惠券码,并重复以上步骤,直到生成的优惠码不在数据库中重复。

## 适用于不同场景的变体

对于需要更多定制化的随机码生成需求,我们可以根据实际场景进行变体。下面是一些常见场景和相应的算法:

- 可重复生成:如需要在一次活动中重复发放相同的优惠码,就可以去掉去重逻辑,直接生成指定数量的优惠码。这样可以避免每次生成新的优惠码都需要去查询数据库,提高生成速度。

  def generate_coupon_codes(length=8, radix=36, prefix='', amount=10):
      """
      生成指定数量、指定长度、指定进制的优惠券码,可以添加前缀,可重复生成
      """
      codes = []
      conn = pymysql.connect(**db_config)
      with conn.cursor() as cursor:
          for _ in range(amount):
              coupon_code = prefix
              while len(coupon_code) < length:
                  coupon_code += int_to_x(random.randint(0, radix ** (length - len(prefix))), radix)
              cursor.execute('INSERT INTO coupon (code) VALUES (%s)', (coupon_code,))
              conn.commit()
              codes.append(coupon_code)
      conn.close()
      return codes
  

- 保持易读和易用:如需要在优惠码中包含易读的单词,可以将36进制替换为62进制,包含数字、小写字母和大写字母等字符,或者在优惠码中插入随机分隔符或格式化字符。

- 防止猜测:如需要保证优惠码难以被猜测,可以增加一些额外的随机性,如在优惠码中插入随机字符、颜色、图片等,或者使用加密算法对优惠码进行加密。

对于每一个调整,我们需要再次检验检查优惠码的有效性。不过大多数情况下,我们仍然可以基于generate_coupon_code这个基础算法进行优化,以产生满足不同需求的优惠码。