📜  生成订单号 (1)

📅  最后修改于: 2023-12-03 15:11:14.077000             🧑  作者: Mango

生成订单号

在电商网站、餐厅外卖、预定旅游等场景中都需要生成订单号,方便后续的处理和追踪。本文将介绍如何生成唯一的订单号,并提供几种实现方式。

方式一:当前时间戳+随机数

一种简单的方式是将当前时间戳转换成字符串,然后加上几位随机数。这样生成的订单号可以基本满足需求,但存在重复的可能性。

import time
import random

order_no = str(int(time.time())) + str(random.randint(100000, 999999))
print(order_no)
# 示例输出:1620888939144662
方式二:UUID

UUID(Universally Unique Identifier)是一种标准格式的唯一标识符,具体实现可以使用Python的内置库 uuid

import uuid

order_no = str(uuid.uuid1())
print(order_no)
# 示例输出:6fbcb126-8b24-11eb-9ffb-00e04c683a8e
方式三:雪花算法

雪花算法是Twitter开源的分布式ID生成算法,在分布式系统中可以生成唯一的、有时间顺序的ID。

以下是Python的实现:

# snowflake.py
# Github:https://github.com/zhengyima/snowflake-py
import threading
import time


class Snowflake(object):
    def __init__(self, worker_id, data_center_id):
        self.worker_id_bits = 5
        self.data_center_id_bits = 5
        self.sequence_bits = 12
        self.epoch = 1288834974657
        self.max_worker_id = -1 ^ (-1 << self.worker_id_bits)
        self.max_data_center_id = -1 ^ (-1 << self.data_center_id_bits)
        self.worker_id_shift = self.sequence_bits
        self.data_center_id_shift = self.worker_id_bits + self.sequence_bits
        self.timestamp_shift = self.data_center_id_bits + self.worker_id_bits + self.sequence_bits
        self.sequence_mask = -1 ^ (-1 << self.sequence_bits)
        self.worker_id = worker_id
        self.data_center_id = data_center_id
        self.sequence = 0
        self.last_timestamp = -1

        self.lock = threading.Lock()

        if worker_id > self.max_worker_id or worker_id < 0:
            raise ValueError('worker_id out of range')
        if data_center_id > self.max_data_center_id or data_center_id < 0:
            raise ValueError('data_center_id out of range')

    def _gen_timestamp(self):
        return int(time.time() * 1000)

    def _next_millis(self, last_timestamp):
        timestamp = self._gen_timestamp()
        while timestamp <= last_timestamp:
            timestamp = self._gen_timestamp()
        return timestamp

    def _get_id(self):
        timestamp = self._gen_timestamp()
        if timestamp < self.last_timestamp:
            raise ValueError('Clock moved backwards. Refusing to generate id for %d milliseconds' % (self.last_timestamp - timestamp))
        if self.last_timestamp == timestamp:
            self.sequence = (self.sequence + 1) & self.sequence_mask
            if self.sequence == 0:
                # Sequence Exhausted, wait till next millisecond.
                timestamp = self._next_millis(self.last_timestamp)
        else:
            self.sequence = 0
        self.last_timestamp = timestamp
        return ((timestamp - self.epoch) << self.timestamp_shift) | (self.data_center_id << self.data_center_id_shift) | (self.worker_id << self.worker_id_shift) | self.sequence

    def get_id(self):
        with self.lock:
            return self._get_id()


if __name__ == '__main__':
    sf = Snowflake(worker_id=1, data_center_id=1)
    order_no = sf.get_id()
    print(order_no)
总结

以上是三种生成订单号的方法,根据不同的需求可以选择适合的实现方式。其中UUID和雪花算法生成的订单号无重复性,唯一性得到保障,适用于对唯一性有较高要求的场景。而当前时间戳加随机数可以方便快捷,适用于一些简单应用。