代码 PHP 唯一卡号生成

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

唯一卡号生成

功能概述

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

推荐文章

如何优化网页的 SEO 架构
2024-11-18 14:32:08 +0800 CST
Python上下文管理器:with语句
2024-11-19 06:25:31 +0800 CST
js函数常见的写法以及调用方法
2024-11-19 08:55:17 +0800 CST
使用Vue 3和Axios进行API数据交互
2024-11-18 22:31:21 +0800 CST
JavaScript数组 splice
2024-11-18 20:46:19 +0800 CST
2024年微信小程序开发价格概览
2024-11-19 06:40:52 +0800 CST
php 统一接受回调的方案
2024-11-19 03:21:07 +0800 CST
Vue3 中提供了哪些新的指令
2024-11-19 01:48:20 +0800 CST
WebSocket在消息推送中的应用代码
2024-11-18 21:46:05 +0800 CST
deepcopy一个Go语言的深拷贝工具库
2024-11-18 18:17:40 +0800 CST
JavaScript 异步编程入门
2024-11-19 07:07:43 +0800 CST
使用 Git 制作升级包
2024-11-19 02:19:48 +0800 CST
Hypothesis是一个强大的Python测试库
2024-11-19 04:31:30 +0800 CST
16.6k+ 开源精准 IP 地址库
2024-11-17 23:14:40 +0800 CST
Vue中的`key`属性有什么作用?
2024-11-17 11:49:45 +0800 CST
FcDesigner:低代码表单设计平台
2024-11-19 03:50:18 +0800 CST
Vue 3 中的 Watch 实现及最佳实践
2024-11-18 22:18:40 +0800 CST
使用Python实现邮件自动化
2024-11-18 20:18:14 +0800 CST
windows下mysql使用source导入数据
2024-11-17 05:03:50 +0800 CST
在Rust项目中使用SQLite数据库
2024-11-19 08:48:00 +0800 CST
支付宝批量转账
2024-11-18 20:26:17 +0800 CST
程序员茄子在线接单