1. 程式人生 > >兌換碼編碼方案實踐

兌換碼編碼方案實踐

兌換碼編碼設計

需求簡介

當前各個業務系統,只要涉及到產品銷售,就離不開大大小小的運營活動需求,其中最普遍的就是兌換碼需求,無論是線下活動或者是線上活動,都能起到良好的宣傳效果。

兌換碼:由一系列字元組成,每一個兌換碼對應系統中的一組資訊,可以是優惠資訊(優惠券),也可以是相關獎品資訊。

在實際的運營活動中,要求兌換碼是唯一的,每一個兌換碼對應一個優惠資訊,而且需求量往往比較大(實際上的需求只有預期的十分之一),兌換碼資訊儘可能的簡潔,並且能對這些兌換碼資訊進行管理(檢視兌換碼,失效兌換碼,統計兌換碼的使用情況)

兌換碼特點

通過上述分析,能夠發現兌換碼有以下幾個特點:
- 兌換碼具有唯一性
- 兌換碼儘可能簡潔
- 兌換碼的量級大

並且由於營運活動的特殊性,要求兌換碼能夠提前生成,這樣可以儘可能的為活動進行預熱(-_-!!!),兌換碼需要具有唯一性,那麼每一個兌換碼必須是不同的;並且要求簡潔,那麼兌換碼的長度不能太長;量級大,且之前也提到兌換碼屬於廣撒網的策略,所以利用率低,也就不適合使用資料庫進行儲存(佔空間,有效的資料有少)

那麼就需要設計一種有效的兌換碼生成策略,支援預先生成,支援校驗,內容簡潔,生成的兌換碼都具有唯一性,那麼這種策略就是一種特殊的編解碼策略,按照約定的編解碼規則支撐上述需求。

設計思路

既然是一種編解碼規則,那麼需要約定編碼空間,編碼空間由字元a-z,A-Z,數字0-9組成,為了增強兌換碼的可識別度,剔除大寫字母O以及I,可用字元如下所示,共60個字元:

abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXZY0123456789 

之前說過,兌換碼要求近可能簡潔,那麼設計是酒需要考慮兌換碼的字元數,假設上線為12位,而字元空間有60位,那麼可以表示的空間範圍為60^12=130606940160000000000000,轉換成2進位制:1001000100000000101110011001101101110011000000000000000000000(61位)

  • 兌換碼組成成分分析

兌換碼可以預先生成,並且不需要額外的儲存空間儲存這些資訊,每個兌換碼對應一種優惠方案,每個兌換碼有自己的編號,防止重複,為了保證兌換碼的有效性,對兌換碼的資料需要進行校驗,當前兌換碼的資料組成如下所示:

優惠方案id
+ 兌換碼序列號 + 校驗碼

各個組成成分的編碼設計

*  兌換碼序列號i,代表當前兌換碼是當前活動中第i個兌換碼,兌換碼序列號的空間範圍決定了優惠活動可以發行的兌換碼數目,當前採用30位bit位表示,可表示範圍:1073741824(10億優惠券)
*  優惠方案id,代表當前優惠方案的id號,優惠方案的空間範圍決定了可以組織的優惠活動次數,當前採用15位表示,可以表示範圍:32768(考慮到運營活動的頻率,以及id的初始值10000,15位足夠,365天每天有運營活動,可以使用54年)
*  校驗位,校驗兌換碼是否有效,主要為了快捷的校驗兌換碼資訊的是否正確,其次可以起到填充資料的目的,增強資料的雜湊性,使用13位表示校驗位,其中分為兩部分,前6位和後7位
兌換碼編號生成演算法
* 生成演算法 
public static long enRedeemNum(long couponSchemeId, long redeemSerialNum) {
    redeemSerialNum = redeemSerialNum << REDEEM_SERIAL_NUM_LS;
    long r = couponSchemeId | redeemSerialNum;
    long n = numOfOne(r);
    long re = r % DIVISOR;
    r = (r << NUMBER_OF_ONE_LS) | n;
    r = (r << REMAINDER_LS) | re;
    return r;
}
編碼演算法
public static long [] deRedeemNum(long redeemNum) {
    long couponSchemeId = redeemNum & COUPON_SCHEME_ID_MASK;
    long redeemSerialNum = redeemNum & REDEEM_SERIAL_NUM_MASK;
    couponSchemeId = couponSchemeId >> COUPON_SCHEME_ID_RS;
    redeemSerialNum = redeemSerialNum >> REDEEM_SERIAL_NUM_RS;
    return new long[] { couponSchemeId, redeemSerialNum };
}
校驗演算法
public static boolean checkVaild(long redeemNum) {
    if (redeemNum > 0) {
        long checkSum = redeemNum & REMAINDER_MASK;
        long n = (redeemNum & NUMBER_OF_ONE_MASK) >> NUMBER_OF_ONE_RS;
        long r = (redeemNum & SUM_MASK) >> SUM_RS;
        if (numOfOne(r) == n) {
            if (r % DIVISOR == checkSum) {
                return Boolean.TRUE;
            }
        }
    }
    return Boolean.FALSE;
}
兌換碼編碼到兌換碼對映方式

當前可以生成唯一的兌換碼編碼資訊,需要將此資訊對映到對應的字元空間中,並且字元空間是可自定義的,當前採用的進位制換算的方式,將兌換碼編碼資訊換算成指定進位制的數,對於進位制的每一位進行編碼例如:

十進位制轉換成二進位制
    17
    17/2 = 8 ... 1
    8/2  = 4 ... 0
    4/2  = 2 ... 0
    2/2  = 1 ... 0
    1/2  = 0 ... 1
十進位制轉換成n進位制類似
    ....

在得到的相應進製表示後,在將進制中的沒一位對映到字元空間中(n表示字元空間的大小)
這個對映關係是可以自定義的

private static final char[] r = new char[] {'q', 'w', 'e', '8', 'a', 's', '2', 'd', 'z', 'x', '9', 'c', '7', 'p',
            '5', 'i', 'k', '3', 'm', 'j', 'u', 'f', 'r', '4', 'v', 'y', 'l', 't', 'n', '6', 'b', 'g', 'h'};

(字母大小寫,數字混排)

n進位制換算以及對映演算法
public static String enRedeemCode(long redeemNum) {
    char[] buf = new char[32];
    int charPos = 32;
    while ((redeemNum / l) > 0) {
        int ind = (int) (redeemNum % l);
        buf[--charPos] = r[ind];
        redeemNum /= l;
    }
    buf[--charPos] = r[(int) (redeemNum % l)];
    String str = new String(buf, charPos, (32 - charPos));
    return str;
}
兌換碼解碼
public static long deRedeemCode(String redeemCode) {
    char chs[] = redeemCode.toCharArray();
    long res = 0L;
    for (int i = 0; i < chs.length; i++) {
        int ind = -1;
        for (int j = 0; j < l; j++) {
            if (chs[i] == r[j]) {
                ind = j;
                break;
            }
        }
        if (ind == -1) {
            return -1;
        }
        if (i > 0) {
        res = res * l + ind;
        } else {
            res = ind;
        }
    }
    return res;
}
  • 計算速度
    • 生成10萬個 花費59ms
    • 生成百萬個,花費530ms
    • 生成一千萬 花費12535ms
85sl4l
2ncu9r
vqdfce
t5p5bg
bnjz3t
wwxyea4
wa4bnyj
wzs8rci
wcjxigc
8t6ktp5
...

相關推薦

兌換編碼方案實踐

兌換碼編碼設計 需求簡介 當前各個業務系統,只要涉及到產品銷售,就離不開大大小小的運營活動需求,其中最普遍的就是兌換碼需求,無論是線下活動或者是線上活動,都能起到良好的宣傳效果。 兌換碼:由一系列字元組成,每一個兌換碼對應系統中的一組資訊,可以是優惠資

刨根究底字符編碼之九——字符編碼方案的演變與字節序

不同 桌面應用 提示 編碼方式 power 同時 建議 travel n) 字符編碼方案的演變與字節序 一、字符編碼方案的演變 1. 前文已經提及,編號字符集CCS(簡稱字符集)與字符編碼方式CEF(簡稱編碼方式)這兩個概念,在早期並沒有必要嚴格區分。 在Unico

提高代編碼的效率,習慣非常重要!

到你 打印 代碼調試 功能點 文件 程序實現 幹凈 4.2 等等 提高代碼編碼的效率,習慣非常重要。經驗分享一下: 1、寫代碼前,先把需求弄清晰(這個非常關鍵):把業務轉化成功能點,有多少個功能點? 2、設計 把業務對象弄清晰,從大到細設計,看看使用什麽設計模

二維快速掃優化方案介紹(一)--怎麽在光線不足時,手機自動進行補光。

ram 平時 implement chang fill change rri ren text 二維碼掃碼已經是一個很通用的技術了,也有很多的開源項目可以實現,比如Zxing項目。https://github.com/zxing 這裏重點不是介紹Zxing中是怎麽樣來實現二

Ceph糾刪編碼機制調研

存儲池 es2017 生成 冷數據 滿足 有著 單位 實現 元素 1 Ceph簡述 Ceph是一種性能優越,可靠性和可擴展性良好的統一的分布式雲存儲系統,提供對象存儲、塊存儲、文件存儲三種存儲服務。Ceph文件系統中不區分節點中心,在理論上可以實現系統規模的無限擴展

虛擬幣交易平臺源解決方案介紹

融雲 ffffff shadow 客戶 com 51cto 前臺 用戶 交易平臺 比融雲海外版虛擬幣交易平臺,是專門為客戶提供的在海外運營的數字資產交易平臺,包含現貨交易、點對點交易。 現貨交易:多種數字資產之間、數字資產與法幣(非人民幣)之間的價格兌換,可將手中的一種數字

企業級代上線方案詳解

代碼上線 代碼備份 軟鏈接 中小型企業代碼上線準則 (1)上線說明****對於重要的升級上線來說先有運維人員備份所有重要數據,然後經過開發人員測試和內部測試成功後直接上傳的站點目錄,出現問題後采用歷史代碼回滾策略。而對普通升級來說,先備份必要數據,然後代碼在開發人員和內外網測試成功後可直接上線。(

每日一讀:《 關於定義Python源代編碼

文字 nts unicode文件 magic nature file local beginning cape 官方pep原文:Abstract:This PEP proposes to introduce a syntax to declare the encoding

SAP ERP接口解決方案實踐

tools 結合 splay 協同 nbsp creating rgb aps iss 轉載自:https://blog.csdn.net/xiaoyw71/article/details/77651101?utm_source=tuicool&utm_medium

Salesforce 開發整理(五)代開發最佳實踐

pdf fir 應該 hid lang perf PE pan 單詞   在Salesforce項目實施過程中,對項目代碼的維護可以說占據極大的精力,無論是因為項目的叠代,還是需求的變更,甚至是項目組成員的變動,都不可避免的需要維護之前的老代碼,而事實上,幾乎沒有任何一個項

Linux實戰教學筆記40: Mha-Atlas-MySQL高可用方案實踐(二)

broadcast level lis 失敗 mat password cti overruns red 六,配置VIP漂移 主機名 IP地址(NAT) 漂移VIP 描述 mysql-db01 eth0:192.168.0.51 VIP:192.168.0.6

淺談皇冠體育源搭建接水修復 PHP代優化最佳實踐

php教程編寫好的PHP代碼是創建快速穩定Web應用的關鍵一步。從一開始就遵循一些最佳實踐技巧將節省後期填坑的時間。 盡可能的使用PHP的內置方法[皇冠體育源碼搭建bbs.yasewl.com請添加鏈接描述只要可以盡可能的使用PHP的內置方法,而不是自己編寫相同功能的方法。花點時間去熟悉和學習PHP的內置

dotnet core Linux下圖片驗證解決方案

https tps 3.0 驗證碼 code 地址 hub 圖片 dot 方案來源:https://github.com/zkweb-framework/zkweb.system.drawing 百度大多都是安裝libgdiplus方法 不說了 然後驗證碼亂碼問題在上面地址

編碼最佳實踐——單一職責原則

SOLID是一組最佳編碼實踐的首字母縮寫 S 單一職責原則 O 開放與封閉原則 L Liskov(裡式)替換原則 I 介面分離原則 D 依賴注入原則 同時應用這些最佳實踐,可以提升程式碼適應變更的能力。但是凡事要有度,過度使用雖然可以讓程式碼有很高的自適應能力,但是會導致層次粒度

編碼最佳實踐——開放封閉原則

開放封閉原則定義 開放與封閉原則有兩種不同的定義,分別是20世紀80年代最原始的定義和後期一個更現代的定義,後者對前者進行更加詳盡的闡述。 Meyer的定義 軟體實體應該允許擴充套件,但禁止修改 ​ ——《面向物件軟體構造》 Martin的定義 ”對於擴充套件是

Windows下git和雲使用實踐

都說github.com賬號是資深程式設計師的標配。奈何國外的網速感人,為了用著方便,可以選國內口碑比較好的gitee.com(碼雲)作為程式碼託管站點。 1.安裝git,設定Path環境變數使得cmd下可以直接用git命令    安裝版本為Git for Wi

CTF每日一題之ACII編碼

好久沒寫了。。。因為好久沒做題了,最近又開始偷懶了,愁人。今天發現了一個新的CTF平臺,很有意思,不過缺點是沒有中文,不過這沒有關係,誰叫我谷歌翻譯用的賊6,今天是個簽到題,就不多說了。 題目連結:http://www.wechall.net/en/challenge/training/enco

通訊原理---FPGA---HDB3編碼

 參考資料: 樊昌信,曹麗娜 . 《通訊原理》(第7版) https://wenku.baidu.com/view/24b7bc227fd5360cba1adb6c  (這個PPT給了很多啟發) https://wenku.baidu.com/view/7cd94

刨根究底字元編碼之——簡體漢字編碼方案(GB2312、GBK、GB18030、GB13000)以及全形、半形、CJK

一、概述 1. 英文字母再加一些其他標點字元之類的也不會超過256個,用一個位元組來表示一個字元就足夠了(2^8 = 256)。但其他一些文字不止這麼多字元,比如中文中的漢字就多達10多萬個,一個位元組只能表示256個字元,肯定是不夠的,因此只能使用多個位元組來表示一個字元。 於是當計算

支付寶移動端動態化方案實踐

兩個 adb color eight intercept 模塊 成本 有助於 targe 小螞蟻說: 此前分享的《模塊化與解耦式開發在螞蟻金服mPaaS深度實踐探討》(想要了解更多相關內容,歡迎關註公眾號:mPaaS )已經對支付寶在移動端開發架構的設計思路有了初步了解