代码 PHP 唯一卡号生成

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

唯一卡号生成

功能概述

该 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 算法 卡号生成 软件开发

推荐文章

免费常用API接口分享
2024-11-19 09:25:07 +0800 CST
微信内弹出提示外部浏览器打开
2024-11-18 19:26:44 +0800 CST
Dropzone.js实现文件拖放上传功能
2024-11-18 18:28:02 +0800 CST
前端如何给页面添加水印
2024-11-19 07:12:56 +0800 CST
智慧加水系统
2024-11-19 06:33:36 +0800 CST
GROMACS:一个美轮美奂的C++库
2024-11-18 19:43:29 +0800 CST
MySQL 日志详解
2024-11-19 02:17:30 +0800 CST
html一些比较人使用的技巧和代码
2024-11-17 05:05:01 +0800 CST
使用Ollama部署本地大模型
2024-11-19 10:00:55 +0800 CST
Flet 构建跨平台应用的 Python 框架
2025-03-21 08:40:53 +0800 CST
H5保险购买与投诉意见
2024-11-19 03:48:35 +0800 CST
html流光登陆页面
2024-11-18 15:36:18 +0800 CST
任务管理工具的HTML
2025-01-20 22:36:11 +0800 CST
File 和 Blob 的区别
2024-11-18 23:11:46 +0800 CST
在Rust项目中使用SQLite数据库
2024-11-19 08:48:00 +0800 CST
前端开发中常用的设计模式
2024-11-19 07:38:07 +0800 CST
程序员茄子在线接单