随机生成优惠券码——`generate_coupon_code`
生成优惠券码是一个很常见的需求,普遍应用于折扣促销、新用户注册、节日慰问等场景中。他们都需要一定的随机性,以保证 性和安全性,同时也需要一定的规则,以便存储和检索。
本文介绍一个简单的生成优惠券码的算法——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这个基础算法进行优化,以产生满足不同需求的优惠码。
