niki/vendor/github.com/brianvoe/gofakeit/v6/finance.go

129 lines
2.7 KiB
Go
Raw Normal View History

2024-04-26 19:30:35 +00:00
package gofakeit
import (
"math/rand"
"strconv"
"unicode"
)
const cusipStr = upperStr + numericStr
// CUSIP
func Cusip() string {
return cusip(globalFaker.Rand)
}
func (f *Faker) Cusip() string {
return cusip(f.Rand)
}
func cusip(r *rand.Rand) string {
cusipBytes := make([]byte, 8)
for i := 0; i < len(cusipBytes); i++ {
cusipBytes[i] = byte(cusipStr[r.Intn(len(cusipStr))])
}
baseCusip := string(cusipBytes)
chkDigit := cusipChecksumDigit(baseCusip)
return baseCusip + chkDigit
}
// ISIN
func Isin() string {
return isin(globalFaker.Rand)
}
func (f *Faker) Isin() string {
return isin(f.Rand)
}
func isin(r *rand.Rand) string {
countryCode := CountryAbr()
nsin := cusip(r)
isinChkDig := isinChecksumDigit(countryCode + nsin)
return countryCode + nsin + isinChkDig
}
// cusipChecksumDigit returns the checksum digit for a CUSIP
func cusipChecksumDigit(cusip string) string {
sum := 0
for i, c := range cusip {
v := 0
if unicode.IsDigit(c) {
v = int(c - '0')
}
if unicode.IsLetter(c) {
//0-indexed ordinal position of Letter + 10
v = int(c-'A') + 10
}
if i%2 != 0 {
// Multiply odd digits by two
v = v * 2
}
sum = sum + int(v/10) + v%10
}
return strconv.Itoa((10 - (sum % 10)) % 10)
}
// isinChecksumDigit returns the checksum digit for an ISIN
func isinChecksumDigit(isin string) string {
isinDigits := make([]int, 0)
for _, c := range isin {
if unicode.IsLetter(c) {
letterVal := int(c) - 55
// Each digit is added as a separate value
isinDigits = append(isinDigits, letterVal/10)
isinDigits = append(isinDigits, letterVal%10)
}
if unicode.IsDigit(c) {
isinDigits = append(isinDigits, int(c-'0'))
}
}
oddSum := 0
evenSum := 0
// Take the per digit sum of the digitized ISIN, doubling even indexed digits
for i, d := range isinDigits {
if i%2 == 0 {
elem := 2 * d
if elem > 9 {
// If the element now has two digits, sum those digits
elem = (elem % 10) + (elem / 10)
}
evenSum += elem
} else {
oddSum += d
}
}
return strconv.Itoa((10 - (oddSum+evenSum)%10) % 10)
}
// Lookup Adds
func addFinanceLookup() {
AddFuncLookup("cusip", Info{
Display: "CUSIP",
Category: "finance",
Description: "Unique identifier for securities, especially bonds, in the United States and Canada",
Example: "38259P508",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return cusip(r), nil
},
})
AddFuncLookup("isin", Info{
Display: "ISIN",
Category: "finance",
Description: "International standard code for uniquely identifying securities worldwide",
Example: "CVLRQCZBXQ97",
Output: "string",
Generate: func(r *rand.Rand, m *MapParams, info *Info) (any, error) {
return isin(r), nil
},
})
}