fbzhong / couponcode

Implementation of Perl's Algorithm::CouponCode for Go / Golang

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CouponCode for Go

An implementation of Perl's [Algorithm::CouponCode][couponcode] for Golang.

Synopsis

This package helps generate and validate coupon codes which could be used for ecommerce coupons. It avoids creating coupons containing certain 'bad words' which may be offensive.

The package provides a default configuration for codes of 3 parts of 4 characters separated by a '-'. The default configuration can be accessed using the Default package field or, for convenience, two top level functions:

Generate() string to generate a coupon code Validate(code string) (string, error) to normalize and validate a code

package couponcode_test

import (
	"fmt"

	"github.com/fbzhong/couponcode"
)

func main() {
	code := couponcode.Generate()
	fmt.Println(code)
	// Output: RCMD-CRVF-FK36
}

To use a custom part and part length, create a new generator using the constructor and then use the functions provided by that instance:

cc := couponcode.New(4, 6)

code := cc.Generate() // note function of cc, not couponcode package

validated, err := cc.Validate(code)

Now, when someone types their code in, you can check that it is valid. This means that letters like O are converted to 0 prior to checking. The validate command returns a normalized code (useful for any consistent database lookups of the coupon code) and an error to indicate if the code was valid.

// same code, just lowercased
code, err := couponcode.Validate('55g2-dhm0-50nn');
// '55G2-DHM0-50NN'

// various letters instead of numbers
code, err := couponcode.Validate('SSGZ-DHMO-SONN');
// '55G2-DHM0-50NN'

// wrong last character
code, err := couponcode.Validate('55G2-DHM0-50NK');
// err != nil

// not enough chars in the 2nd part
code, err := couponcode.Validate('55G2-DHM-50NN');
// err != nil

The first thing we do to each code is uppercase it. Then we convert the following letters to numbers:

  • O -> 0
  • I -> 1
  • Z -> 2
  • S -> 5

This means [oizs], [OIZS] and [0125] are considered the same code.

Example

Let's say you want a user to verify they got something, whether that is an email, letter, fax or carrier pigeon. To prove they received it, they have to type the code you sent them into a certain page on your website. You create a code which they have to type in:

code := couponcode.Generate();
// 55G2-DHM0-50NN

Time passes, letters get wet, carrier pigeons go on adventures and faxes are just as bad as they ever were. Now the user has to type their code into your website. The problem is, they can hardly read what the code was. Luckily we're somewhat forgiving since Z's and 2's are considered the same, O's and 0's, I's and 1's and S's and 5's are also mapped to each other. But even more than that, the 4th character of each group is a checkdigit which can determine if the other three in that group are correct. The user types this:

[s5g2-dhmo-50nn]

Because our codes are case insensitive and have good conversions for similar chars, the code is accepted as correct.

Also, since we have a checkdigit, we can use a client-side plugin to highlight to the user any mistake in their code before they submit it. Please see the original project ([Algorithm::CouponCode][couponcode]) for more details of client side validation.

Installation

The easiest way to get it is via go get:

$ go get -u github.com/fbzhong/couponcode

Build

The default build uses the random number generator from the crypto/rand package for more secure random number generation.

Tests

To run the tests, use go test:

$ go test

Author

Inspired By

Grant McLean's [Algorithm::CouponCode][couponcode] - with thanks. :)

License

MIT.

About

Implementation of Perl's Algorithm::CouponCode for Go / Golang


Languages

Language:Go 100.0%