涡小蜂

涡小蜂

资源分享

Charles激活码算法&&汉化补丁

只剩寒暄 源码 23 次阅读
Charles激活码算法&&汉化补丁

Charles 激活码核心算法

Charles 激活码生成机制的核心是一套自定义分组加密算法,足够清晰且可直接运行。

一、核心代码

import struct
import random
from ctypes import c_int32, c_uint32

# 算法常量
ROUNDS = 12
ROUND_KEYS = 2 * (ROUNDS + 1)
CK_NAME = 0x7a21c951691cd470
CK_KEY = -5408575981733630035
MAGIC_NUMBER_1 = -1209970333
MAGIC_NUMBER_2 = -1640531527
MAGIC_NUMBER_3 = 0x54882f8a
SPECIAL_VALUES = {0x0401, 0x0402, 0x0403}

# 掩码与移位常量
MASK_32 = 0xFFFFFFFF
MASK_64 = 0xFFFFFFFFFFFFFFFF
MASK_8 = 0xFF
SHIFT_32 = 32
ROTATE_BITS = 0x3

# 基础工具函数
def rotate_left(x: int, y: int) -> int:
    """32位左旋转"""
    y &= 0x1F
    x_uint = c_uint32(x).value
    return (x << y) | (x_uint >> (32 - y))

def rotate_right(x: int, y: int) -> int:
    """32位右旋转"""
    y &= 0x1F
    x_uint = c_uint32(x).value
    return (x_uint >> y) | (x << (32 - y))

def pk_long(a: int, b: int) -> int:
    """组合两个32位整数为64位"""
    return (a & MASK_32) | (b << SHIFT_32)

def get_signed_byte(byte: int) -> int:
    """转换字节为有符号值"""
    return struct.unpack('b', bytes([byte]))[0] if byte > 127 else byte

# CK加密算法核心
class CkCipher:
    def __init__(self, ck_key: int):
        self.ck_key = ck_key
        self.rk = [0] * ROUND_KEYS
        self._init_round_keys()

    def _init_round_keys(self) -> None:
        """初始化轮密钥"""
        ld = [
            c_int32(self.ck_key & MASK_32).value,
            c_int32((self.ck_key >> SHIFT_32) & MASK_32).value
        ]

        self.rk[0] = MAGIC_NUMBER_1
        for i in range(1, ROUND_KEYS):
            self.rk[i] = c_int32(self.rk[i-1] + MAGIC_NUMBER_2).value

        a, b, i, j = 0, 0, 0, 0
        for _ in range(3 * ROUND_KEYS):
            self.rk[i] = rotate_left(c_int32(self.rk[i] + (a + b)).value, 3)
            a = self.rk[i]
            ld[j] = rotate_left(c_int32(ld[j] + (a + b)).value, a + b)
            b = ld[j]
            i = (i + 1) % ROUND_KEYS
            j = (j + 1) % 2

    def encrypt(self, in_val: int) -> int:
        """加密64位数据"""
        a = c_int32((in_val & MASK_32) + self.rk[0]).value
        b = c_int32(((in_val >> SHIFT_32) & MASK_32) + self.rk[1]).value

        for r in range(1, ROUNDS + 1):
            idx1 = 2 * r
            idx2 = idx1 + 1
            a = rotate_left(a ^ b, b) + self.rk[idx1]
            a = c_int32(a).value
            b = rotate_left(b ^ a, a) + self.rk[idx2]
            b = c_int32(b).value

        return pk_long(a, b)

    def decrypt(self, in_val: int) -> int:
        """解密64位数据"""
        a = c_int32(in_val & MASK_32).value
        b = c_int32((in_val >> SHIFT_32) & MASK_32).value

        for i in range(ROUNDS, 0, -1):
            idx1 = 2 * i + 1
            idx2 = 2 * i
            b = rotate_right(b - self.rk[idx1], a) ^ a
            b = c_int32(b).value
            a = rotate_right(a - self.rk[idx2], b) ^ b
            a = c_int32(a).value

        b = c_int32(b - self.rk[1]).value
        a = c_int32(a - self.rk[0]).value
        return pk_long(a, b)

# 激活码生成核心逻辑
def generate_charles_key(text: str) -> str:
    """生成Charles激活码"""
    if not text.strip():
        raise ValueError("生成名称不能为空")

    # 用户名预处理
    name_bytes = text.encode('utf-8')
    name_len = len(name_bytes)
    total_len = name_len + 4
    padded_len = ((-total_len) & 7) + total_len
    padded_len = max(padded_len, 8)

    buff = bytearray()
    buff.extend(struct.pack('>I', name_len))
    buff.extend(name_bytes)
    buff.extend(b'\x00' * (padded_len - len(buff)))

    # 第一轮加密(名称加密)
    ck_name = CkCipher(CK_NAME)
    out_buff = bytearray()
    for i in range(0, padded_len, 8):
        chunk = buff[i:i+8].ljust(8, b'\x00')
        now_var = struct.unpack('>Q', chunk)[0]
        encrypted = ck_name.encrypt(now_var)
        out_buff.extend(struct.pack('>Q', encrypted & MASK_64))

    # 计算前缀特征值
    n = 0
    for b in out_buff:
        n = rotate_left(n ^ get_signed_byte(b), ROTATE_BITS)
    prefix = c_int32(n ^ MAGIC_NUMBER_3).value

    # 生成随机后缀
    suffix = random.randint(0, 0x7FFFFFFF)
    in_val = (prefix << SHIFT_32) & (MASK_32 << SHIFT_32)
    suffix_high = suffix >> 16

    if suffix_high in SPECIAL_VALUES:
        in_val |= c_uint32(suffix).value
    else:
        in_val |= 0x01000000 | (c_uint32(suffix).value & 0xFFFFFF)

    # 第二轮解密生成核心码
    ck_key = CkCipher(CK_KEY)
    out = ck_key.decrypt(in_val)

    # 计算校验位
    n2 = 0
    for i in range(56, -8, -8):
        n2 ^= (in_val >> i) & MASK_8
    vv = abs(c_int32(n2 & MASK_8).value)

    return f"{vv:02x}{out & MASK_64:016x}"

# 测试示例
if __name__ == "__main__":
    test_name = "test_charles_user"
    try:
        key = generate_charles_key(test_name)
        print(f"名称:{test_name}")
        print(f"激活码:{key}")
    except Exception as e:
        print(f"生成失败:{e}")

二、核心逻辑说明

1. 基础运算

  • 旋转运算:区别于普通移位,旋转会将移出的比特位补到另一侧,是分组加密的核心操作;
  • 64 位组合:将两个 32 位整数拼接为 64 位数据,适配分组加密的长度要求;
  • 有符号处理:通过 c_int32保证 32 位有符号整数运算,与原生算法逻辑一致。

2. CK 加密算法

  • 轮密钥生成:基于固定密钥生成 26 个轮密钥(12 轮加密每轮 2 个,加初始密钥);
  • 加密流程:12 轮 Feistel 结构,对 64 位数据逐轮做 “异或→旋转→加轮密钥” 运算;
  • 解密流程:逆序执行加密的反向操作,还原原始数据。

3. 激活码生成流程

  1. 用户名预处理:转 UTF-8 字节,拼接长度前缀,按 8 字节分组补 0;
  2. 名称加密:用 CK_NAME 密钥加密预处理后的用户名数据;
  3. 特征值计算:基于加密结果生成用户名唯一前缀;
  4. 随机后缀生成:生成随机数并做特殊值过滤,避免无效码;
  5. 核心码解密:用 CK_KEY 密钥解密 “前缀 + 后缀” 组合数据;
  6. 校验位拼接:计算 1 字节校验位,最终生成 “2 位校验位 + 16 位核心码” 格式的激活码。

3. 使用方式

只需调用 generate_charles_key函数,传入任意非空字符串即可生成激活码:

key = generate_charles_key("your_custom_name")
print(key)

官方链接

仅用于学习和研究Charles软件的工作原理,请勿用于商业用途。如有条件,请支持官方正版。

下载链接:charles下载链接

购买链接:charles购买链接

在线生成

生成链接:Charles激活码生成

汉化补丁

替换/lib目录 charles.jar文件

下载链接:Charles v5.0.3汉化补丁 密码:5z9h

发表评论

0 / 500
请先 登录 再评论

暂无评论

成为第一个评论的人吧!