代码 PHP 唯一卡号生成

2024-11-18 21:24:12 +0800 CST views 662

唯一卡号生成

功能概述

该 PHP 类 TkCardFlake 用于生成预付卡卡号。它通过时间戳、序号、工作节点 ID 和 Luhn 校验算法来生成唯一且符合卡号格式的字符串。

主要功能模块

  1. 类常量

    • INIT_DATE: 初始时间戳,用于计算相对时间。
    • SEQUENCE_MAX: 序列号的最大值,限制在 999 以内。
  2. 构造函数

    • 初始化类的实例,设置 workerIdworkerId 不能超过 9,否则抛出异常。
  3. GetCardInfo 方法

    • 生成卡号的核心方法,通过当前时间戳和序列号生成卡号,并附加 Luhn 校验码。
  4. now 方法

    • 返回当前的 Unix 时间戳(秒)。
  5. luhnCheck 方法

    • 实现 Luhn 算法,用于生成卡号的校验码。

代码优化与说明

<?php

namespace Extend;

use Exception;

// 生成预付卡卡号
class TkCardFlake
{
    // 初始化常量
    public const INIT_DATE    = 1691352000; // '2023-08-07 04:00:00 000';
    public const SEQUENCE_MAX = 999; // 序号最大值

    public int $workerId  = 0;
    public int $sequence  = 0;
    public int $timestamp = 0;

    /**
     * 构造函数,初始化 workerId
     * @param int $workerId
     * @throws Exception
     */
    public function __construct(int $workerId = 0)
    {
        if ($workerId > 9) {
            throw new Exception('生成卡号失败,workerId不能大于9。');
        }
        $this->workerId = $workerId;
    }

    /**
     * 生成卡号
     * @param string $cardBin 卡片前缀
     * @return string
     * @throws Exception
     */
    public function GetCardInfo(string $cardBin): string
    {
        $now = $this->now();

        if ($this->timestamp == $now) {
            $this->sequence++;
            if ($this->sequence > self::SEQUENCE_MAX) {
                // 当前毫秒内生成的序号已经超出最大范围,等待下一毫秒
                do {
                    $now = $this->now();
                } while ($now <= $this->timestamp);
            }
        } else {
            $this->timestamp = $now;
            $this->sequence  = 0;
        }

        $difftime = str_pad($this->timestamp - self::INIT_DATE, 10, '0', STR_PAD_LEFT);
        $sequence = str_pad($this->sequence, 3, '0', STR_PAD_LEFT);

        // 拼接卡号: workerId(1位) + difftime(10位) + sequence(3位)
        $no = $this->workerId . $difftime . $sequence;
        $cardBinNo = $cardBin . $no;

        // 计算Luhn校验码
        $checkNo = $this->luhnCheck($cardBinNo) % 10 == 0 ? 0 : 10 - ($this->luhnCheck($cardBinNo) % 10);

        return $cardBinNo . $checkNo;
    }

    /**
     * 获取当前秒级时间戳
     * @return string
     */
    private function now(): string
    {
        return time();
    }

    /**
     * 计算Luhn校验和
     * @param string $number
     * @return int
     */
    private function luhnCheck(string $number): int
    {
        $reversedNumber = strrev($number);
        $sum = 0;

        for ($i = 0; $i < strlen($reversedNumber); $i++) {
            $digit = (int)$reversedNumber[$i];
            if ($i % 2 == 1) {
                $digit *= 2;
                if ($digit > 9) {
                    $digit -= 9;
                }
            }
            $sum += $digit;
        }

        return $sum;
    }
}

代码功能说明

  1. 类属性与常量

    • INIT_DATE: 起始时间,用于计算相对时间。
    • SEQUENCE_MAX: 每秒最多生成 1000 个卡号。
  2. GetCardInfo 方法

    • 根据当前时间戳、序列号和 workerId 生成卡号。
    • 使用 Luhn 算法生成校验位。
  3. luhnCheck 方法

    • 反转卡号并对奇数位数字加倍,计算总和来生成校验位。

使用方法

  1. 创建一个 TkCardFlake 实例并传入 workerId
  2. 调用 GetCardInfo 方法并传入卡片前缀(cardBin)来生成卡号。

优化建议

  • 将时间戳和序列号处理封装成独立方法,提高代码复用性。
  • 确保 workerId 在多实例中唯一,以避免生成重复卡号。

总结

这段代码提供了一个生成唯一预付卡号的高效机制,通过时间戳、序列号和 Luhn 校验的组合确保了卡号的唯一性和有效性。

复制全文 生成海报 编程 PHP 算法 卡号生成 软件开发

推荐文章

如何开发易支付插件功能
2024-11-19 08:36:25 +0800 CST
Vue3中如何实现国际化(i18n)?
2024-11-19 06:35:21 +0800 CST
Nginx 负载均衡
2024-11-19 10:03:14 +0800 CST
使用xshell上传和下载文件
2024-11-18 12:55:11 +0800 CST
如何在Rust中使用UUID?
2024-11-19 06:10:59 +0800 CST
智能视频墙
2025-02-22 11:21:29 +0800 CST
goctl 技术系列 - Go 模板入门
2024-11-19 04:12:13 +0800 CST
Vue3中的Scoped Slots有什么改变?
2024-11-17 13:50:01 +0800 CST
7种Go语言生成唯一ID的实用方法
2024-11-19 05:22:50 +0800 CST
Vue 3 中的 Watch 实现及最佳实践
2024-11-18 22:18:40 +0800 CST
如何在 Vue 3 中使用 TypeScript?
2024-11-18 22:30:18 +0800 CST
MySQL 优化利剑 EXPLAIN
2024-11-19 00:43:21 +0800 CST
JavaScript 策略模式
2024-11-19 07:34:29 +0800 CST
Vue3中的v-bind指令有什么新特性?
2024-11-18 14:58:47 +0800 CST
Vue3中的JSX有什么不同?
2024-11-18 16:18:49 +0800 CST
120个实用CSS技巧汇总合集
2025-06-23 13:19:55 +0800 CST
Nginx 跨域处理配置
2024-11-18 16:51:51 +0800 CST
Rust 并发执行异步操作
2024-11-18 13:32:18 +0800 CST
Vue 中如何处理跨组件通信?
2024-11-17 15:59:54 +0800 CST
Flet 构建跨平台应用的 Python 框架
2025-03-21 08:40:53 +0800 CST
程序员茄子在线接单