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 }