2025-05-07 15:03:19 +08:00

312 lines
7.5 KiB
Go

package cdkey
import (
"math"
"math/rand"
)
const (
MAXNUM = math.MaxInt32 - 20000000
CDKEY_LENGTH = 15
MAIN_KEY_LENGTH = 40
NUM_KEY_LENGTH_BINARY = 8
MAIN_KEY_NUM_LENGTH = 32
NUM_KEY_LENGTH = 3
CHECK_LENGTH = 5
BATCH_LENGTH = 20
BATCH_KEY_LENGTH_BINARY = 32
TYPE_LENGTH_BINARY = 32
shuffleLength = 32
exceptShuffleSeedTotalLength = 70
SHUFFLE_INDEX = 14
TYPE_INDEX = 13
BATCH_NUM_BEGIN = 12
BATCH_BEGIN = 8
BATCH_END = 12
MAIN_KEY_BEGIN = 0
MAIN_KEY_END = 8
mainKeyFormat int64 = 34359738367
checkNumFormat int64 = 1065151889408
CHECK_LENGTH_BINARY = 32
)
var toBase32 = []rune{'2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}
var toBase32CToI map[rune]int
var mainKeyBatchKey = newBitmap(20, 1918215104086)
var intFormat int64 = 4294967295
var key = newBitmap(20, 1209617303503)
var shuffleMap = make(map[int][]int)
var numKey = []int64{
3000669867,
3671239387,
2526368469,
2493864681,
3604110165,
3567998377,
2763216037,
2863360677,
}
var batchKey = []*bitmap{
newBitmap(20, 31511741981182095),
newBitmap(20, 3664122353341979125),
newBitmap(20, 3024789513220408272),
newBitmap(20, 7614911559402769357),
newBitmap(20, 2108459002177461007),
newBitmap(20, -3779584974404014377),
newBitmap(20, -4708816669881919040),
newBitmap(20, -6362362468306307184),
newBitmap(20, 5237470582631498811),
newBitmap(20, 5507680150663927504),
newBitmap(20, -533592023685287698),
newBitmap(20, 5175063634818869382),
newBitmap(20, -8744795741519816883),
newBitmap(20, -4080090257317771786),
newBitmap(20, -8036132546007449313),
newBitmap(20, 202953352259602475),
newBitmap(20, 1095317292689077154),
newBitmap(20, 2991873574004670411),
newBitmap(20, -6707239314758981218),
newBitmap(20, 7712241472074747715),
newBitmap(20, -8133590642362246474),
newBitmap(20, -4968343163714505661),
newBitmap(20, -6905628074578549760),
newBitmap(20, 5195681389062354029),
newBitmap(20, -5910830154906229288),
newBitmap(20, -1676518468791541432),
newBitmap(20, -7994149653806568719),
newBitmap(20, -7378005837432330374),
newBitmap(20, 1068884024847281324),
newBitmap(20, 1945505497196485942),
newBitmap(20, -3492268017556027220),
newBitmap(20, 7364928014934311923),
}
var toNumBitSet [NUM_KEY_LENGTH_BINARY]*bitmap
var toBitSet32 [32]*bitmap
func init() {
for i := 0; i < 32; i++ {
temp := i
toBitSet32[i] = newBitmap(5, 0)
for j := 0; j < 5; j++ {
toBitSet32[i].Set(j, (temp&1) == 1)
temp >>= 1
}
}
for i := 0; i < NUM_KEY_LENGTH_BINARY; i++ {
temp := i
toNumBitSet[i] = newBitmap(NUM_KEY_LENGTH, 0)
for j := 0; j < NUM_KEY_LENGTH; j++ {
toNumBitSet[i].Set(j, (temp&1) == 1)
temp >>= 1
}
}
toBase32CToI = make(map[rune]int)
for i := 0; i < len(toBitSet32); i++ {
toBase32CToI[toBase32[i]] = i
}
for seed := 0; seed < shuffleLength; seed++ {
array := make([]int, exceptShuffleSeedTotalLength)
for i := 0; i < exceptShuffleSeedTotalLength; i++ {
array[i] = i
}
shuffle(array, rand.New(rand.NewSource(int64(seed))))
shuffleMap[seed] = array
}
}
func checkIndex(num int64, batch int, batchKeyIndex int, numKeyIndex int) bool {
return (num+int64(batch))%BATCH_KEY_LENGTH_BINARY == int64(batchKeyIndex) && (num+int64(batch))%NUM_KEY_LENGTH_BINARY == int64(numKeyIndex)
}
func numEncode(num int64, index int) int64 {
return numKey[index] ^ num
}
func getNumKeyIndex(mainKeyBitSet *bitmap) int {
bitset := newBitmap(NUM_KEY_LENGTH, 0)
for i := 0; i < bitset.GetSize(); i++ {
bitset.Set(i, mainKeyBitSet.Get(MAIN_KEY_NUM_LENGTH+i))
}
return int(bitset.toInt64())
}
func check(mainkeyBitSet *bitmap) bool {
mainkey := mainkeyBitSet.toInt64()
if mainkey <= 0 {
mainkey = -mainkey
}
beCheckNum := mainkey & mainKeyFormat
checkNum := mainkey & checkNumFormat
checkNum >>= (MAIN_KEY_NUM_LENGTH + NUM_KEY_LENGTH)
return beCheckNum%CHECK_LENGTH_BINARY == checkNum
}
func base32Decode(data string) *bitmap {
if len(data) > 63/5 {
return nil
}
bitset := newBitmap(len(data)*5, 0)
i := 0
for _, c := range data {
if _, find := toBase32CToI[c]; !find {
return nil
}
index := toBase32CToI[c]
letterBitSet := toBitSet32[index]
for j := 0; j < 5; j++ {
bitset.Set(i, letterBitSet.Get(j))
i++
}
}
return bitset
}
func recoverCDKey(cdKey string, index int) string {
array := shuffleMap[index]
if array == nil {
return ""
}
bytes := base32DecodeReturnByteArray(cdKey)
if bytes == nil {
return ""
}
if len(array) != len(bytes) {
return ""
}
resultByte := make([]byte, len(bytes))
for i := 0; i < len(array); i++ {
resultByte[array[i]] = bytes[i]
}
return base32Encode1(resultByte)
}
func shuffleCDKey(key string, index int) string {
array := shuffleMap[index]
bytes := base32DecodeReturnByteArray(key)
resultByte := make([]byte, len(bytes))
for i := 0; i < len(array); i++ {
resultByte[i] = bytes[array[i]]
}
return base32Encode1(resultByte) + string(toBase32[index])
}
func shuffle(array []int, rander *rand.Rand) {
for i := len(array); i > 1; i-- {
swap(array, i-1, rander.Intn(i))
}
}
func swap(array []int, i, j int) {
array[i], array[j] = array[j], array[i]
}
func newEncode(num int64, index int) int64 {
return numKey[index] ^ num
}
func base32Encode(m *bitmap) string {
if m.GetSize()%5 != 0 {
return ""
}
stringBuilder := ""
for i := 0; i < m.GetSize(); i += 5 {
bitset1 := newBitmap(5, 0)
for j := 0; j < 5; j++ {
bitset1.Set(j, m.Get(i+j))
}
if bitset1.toInt64() >= int64(len(toBase32)) {
return ""
}
letter := toBase32[int(bitset1.toInt64())]
stringBuilder += string(letter)
}
return stringBuilder
}
func base32Encode1(bytes []byte) string {
if len(bytes)%5 != 0 {
return ""
}
stringBuilder := ""
for i := 0; i < len(bytes); i += 5 {
bitset1 := newBitmap(5, 0)
for j := 0; j < 5; j++ {
bitset1.Set(j, bytes[i+j] > 0)
}
if bitset1.toInt64() >= int64(len(toBase32)) {
return ""
}
letter := toBase32[int(bitset1.toInt64())]
stringBuilder += string(letter)
}
return stringBuilder
}
func fakeRC4Encode(data, key *bitmap) *bitmap {
if data.GetSize() != key.GetSize() {
return nil
}
bitSet := newBitmap(data.GetSize(), 0)
for i := 0; i < data.GetSize(); i++ {
bitSet.Set(i, data.GetInt(i)^key.GetInt(i) == 1)
}
return bitSet
}
func getMainKey(batch *bitmap) *bitmap {
bitSet := newBitmap(MAIN_KEY_LENGTH, 0)
batchKey := fakeRC4Encode(batch, mainKeyBatchKey)
if batchKey == nil {
return nil
}
index := (int)(batchKey.toInt64()&intFormat) % key.GetSize()
count := 0
for i := 0; i < index; i++ {
bitSet.Set(count, key.Get(i))
count++
}
for i := 0; i < batchKey.GetSize(); i++ {
bitSet.Set(count, batchKey.Get(i))
count++
}
for i := index; i < key.GetSize(); i++ {
bitSet.Set(count, key.Get(i))
count++
}
return bitSet
}
func base32DecodeReturnByteArray(data string) []byte {
bytes := make([]byte, len(data)*5)
i := 0
for _, c := range data {
if _, find := toBase32CToI[c]; !find {
return nil
}
index := toBase32CToI[c]
letterBitSet := toBitSet32[index]
for j := 0; j < 5; j++ {
bitValue := letterBitSet.Get(j)
if bitValue {
bytes[i] = 1
} else {
bytes[i] = 0
}
i++
}
}
return bytes
}