PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/x/daily/luhn/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / x / daily / luhn
Files
3 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/x/daily/luhn/v0
gno
0.9

Files (3)

  • README.mdmarkdown
  • gnomod.tomltoml
  • luhn.gnogno
luhn.gnogno
1// Package luhn implements the Luhn mod-10 checksum (Hans Peter Luhn, 1954) as2// a pure, reusable package: the check used by credit-card numbers, IMEIs and3// many national ID schemes to catch typos and single-digit transpositions.4//5// It is a *checksum*, not a security primitive: it detects every single-digit6// error and almost every adjacent transposition, but it is trivial to forge and7// says nothing about whether an identifier actually exists. Never use it to8// authorize anything on-chain.9//10// No clocks, no randomness, no chain imports — same input, same output.11//12// A live demo of this package is at13// [r/moul/x/daily/luhndemo](/r/moul/x/daily/luhndemo/v0).14package luhn1516import (17	"strings"18)1920// MaxLen bounds an input so validation gas stays predictable.21const MaxLen = 642223// Valid reports whether s carries a correct Luhn check digit.24//25// Spaces and hyphens are ignored, so "4539 1488 0343 6467" and26// "4539-1488-0343-6467" both work. Any other non-digit makes it false, as does27// an empty/1-digit input or one longer than MaxLen. A string of all zeros is28// technically Luhn-valid and is accepted — reject it in the caller if your29// domain needs to.30func Valid(s string) bool {31	digits, ok := clean(s)32	if !ok || len(digits) < 2 {33		return false34	}35	return sum(digits)%10 == 036}3738// CheckDigit returns the digit that must be appended to payload to make the39// whole string Luhn-valid, and whether the payload was usable.40func CheckDigit(payload string) (int, bool) {41	digits, ok := clean(payload)42	if !ok || len(digits) == 0 {43		return 0, false44	}45	// The check digit sits in the "doubled" position of the final number, so46	// compute the sum as if a 0 had already been appended.47	total := sum(append(digits, 0))48	return (10 - total%10) % 10, true49}5051// Append returns payload with its Luhn check digit appended (digits only,52// separators stripped), and whether the payload was usable.53func Append(payload string) (string, bool) {54	d, ok := CheckDigit(payload)55	if !ok {56		return "", false57	}58	digits, _ := clean(payload)59	var b strings.Builder60	for _, x := range digits {61		b.WriteByte(byte('0' + x))62	}63	b.WriteByte(byte('0' + d))64	return b.String(), true65}6667// clean turns s into its digit values, ignoring spaces and hyphens. ok is false68// if any other character appears or the input exceeds MaxLen.69func clean(s string) ([]int, bool) {70	if len(s) > MaxLen {71		return nil, false72	}73	digits := make([]int, 0, len(s))74	for i := 0; i < len(s); i++ {75		c := s[i]76		switch {77		case c >= '0' && c <= '9':78			digits = append(digits, int(c-'0'))79		case c == ' ' || c == '-':80			// separator: ignore81		default:82			return nil, false83		}84	}85	return digits, true86}8788// sum computes the Luhn total: walking right to left, every second digit is89// doubled, and a double of 10 or more has 9 subtracted (equivalent to adding90// its two decimal digits).91func sum(digits []int) int {92	total := 093	double := false94	for i := len(digits) - 1; i >= 0; i-- {95		d := digits[i]96		if double {97			d *= 298			if d > 9 {99				d -= 9100			}101		}102		total += d103		double = !double104	}105	return total106}107

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.