开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 243|回复: 1
收起左侧

[技术专题] 开源雪王口令免单

[复制链接]
结帖率:50% (1/2)
发表于 前天 17:33 | 显示全部楼层 |阅读模式   福建省泉州市
分享一个py并发多账号抢雪王的源码



感谢大家帮忙解密,故现做出回馈!

配置区的token必须修改,自行抓包,不做叙述
代码包含两部分:mxbc.pycdn_sign.js

以下是mxbc.py代码:
import time
import hashlib
import requests
import execjs
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime

# -------------------- 配置 --------------------
USE_PROXY = True  # 是否使用代理
MS_DELAY = 100  # 每条请求间隔(毫秒)
                #http://api.xiequ.cn/VAD/GetIp.aspx?act=get&uid=145115&vkey=D43DF3444A308F29BB1594E44743D39E&num=200&time=30&plat=1&re=1&type=0&so=1&ow=1&spl=1&addr=&db=1
                #http://api.xiequ.cn/VAD/GetIp.aspx?act=get&uid=145115&vkey=D43DF3444A308F29BB1594E44743D39E&num=200&time=30&plat=1&re=1&type=2&so=1&ow=1&spl=1&addr=&db=1
PROXY_API_URL = "http://route.xiongmaodaili.com/xiongmao-web/selfControl/getIP?secret=a90af7283ce2b06282474b749703d0f7&code=1&orderNo=ZK20250519150454K0dmYctE&type=0&returnAccount=1"  # IP代理URL

# ✅ 完整 TOKEN 列表(手机号, token
TOKEN_PAIRS = [
    (
"账号备注1", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ3eF8xNDoxNzQ3MzE4NTQxfQ.WYZUZOGrI_suFQjoPA0HW6Bz9fvhLtobwr4BIDDOEjUNBmPc-6JR5jshY_hNKryFhbGXKg"),
    (
"账号备注2", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ3eG1pbmlfMTkyMzAyNsImlhdCI6MTMyMDA0Mn0.GjNBiwxP8ZQokN7FkoNjtr9Am-4coTZAzFskKcnHT7lob1PA0Q2yjBHKPqoYs3pef8qxL-5qvMZAeemyuBnPuw"),
    ("账号备注3", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJwaG9uZV8xODE4MTUwMIiiaWF0IjoxNzQ3NTU4MzI2fQ.K6PJJKARaBEvOzz_JewicoVKW6iZ-9GK3qMi175bNbgBrqrWpDIJVamNMKGGgi8DoozcQ3EDgusDXp4vr9J-4w"),
    ("账号备注4", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJwaG9uZV8xNDQ5MDoxNzQ3NTU4NTg1fQ.dYl9pT5TQN8iFho_Cbvk5VbPKKmnkpM2gKzylK90maZ_7cmbHmsw098wJ498nGcu5TE3SgZPdvawO6L0KwLulQ"),
    ("账号备注15", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ3eF8xNzkyOTI1NzA4NjI5Mzc3MDI2Ii9h7gUy9Yu8I8GIy8E9wnwPZ14o6syPNQTTd17LdfGXl0bcHduznnsB0yCqDAu21n2VPH_w")
]

JS_FILE =
"cdn_sign.js"  # JS 文件路径
SECRET_WORD = "爆汁蓝莓一口沦陷!" #口令!!!!!每天必须改!!!!!!!!!!!
# ROUND_TIME = "17:00"              # 这部分已经写了区当前时间的整点,注释了,如需开启删除submit_task函数里的ROUND_TIME 即可。SUBMIT_TIMES = 30  # 最大任务数
MAX_WORKERS = 10  # 提高并发数
FIXED_SALT = "c274bac6493544b89d9c4f9d8d542b84"  #固定,不许修改

# -------------------- 加载 JS --------------------
with open(JS_FILE, "r", encoding="utf-8") as f:
    js_code = f.read()
ctx = execjs.compile(js_code)

# -------------------- 工具函数 --------------------
def generate_sign(data: dict) -> str:
    raw = (
        
f"marketingId={data['marketingId'}"
        f"&round={data['round'}"
        f"&s={data['s'}"
        f"&secretword={data['secretword'}"
        f"&stamp={data['stamp'}"
    )
   
return hashlib.md5((raw + FIXED_SALT).encode("utf-8")).hexdigest()

def fetch_proxies() -> list:
   
if not USE_PROXY:
        
return ["直连"]
   
try:
        resp = requests.get(PROXY_API_URL, timeout=
10)
        
if resp.status_code == 200:
            proxies = resp.text.strip().splitlines()
            valid_ips = [ip
for ip in proxies if ":" in ip and len(ip.split(":")) == 2]
            
if valid_ips:
                print(
f"获取到 {len(valid_ips)} 个有效代理 IP")
               
return valid_ips
            
else:
                print(
"代理内容格式异常,将使用直连。")
        
else:
            print(
f"代理请求失败,状态码:{resp.status_code},将使用直连。")
   
except Exception as e:
        print(
f"代理接口异常:{e},将使用直连。")
   
return ["直连"]

def submit_task(phone: str, token: str, proxy_ip: str) -> bool:
    ROUND_TIME = datetime.now().strftime(
'%H:00')
    base_url =
"https://activity.mxbc.net/skc/api/v1/secretword/confirm"
    payload = {
        
"marketingId": "1923016284317048833",
        
"round": ROUND_TIME,
        
"secretword": SECRET_WORD,
        
"s": 2,
        
"stamp": int(time.time() * 1000)
    }
    payload[
"sign"] = generate_sign(payload)
    headers = {
        
"Content-Type": "application/json",
        
"Access-Token": token,
        
"User-Agent": "Mozilla/5.0",
        
"version": "2.5.3"
    }

   
try:
        final_url = ctx.call(
"get_cdn_seaech", base_url, payload)
   
except Exception as e:
        print(
f"[{proxy_ip}] URL 生成失败:{e}")
        
return False

    proxies = {"http": f"http://{proxy_ip}", "https": f"http://{proxy_ip}"} if proxy_ip != "直连" else None

    try:
        resp = requests.post(final_url, headers=headers, json=payload, proxies=proxies, timeout=
5)
        
if resp.status_code == 200:
            print(
f"[{proxy_ip}] [{phone}] 成功: {resp.json()}")
            
return True
        else:
            print(
f"[{proxy_ip}] [{phone}] 失败: 状态码 {resp.status_code}")
            
return False
    except Exception as e:
        print(
f"[{proxy_ip}] [{phone}] 请求异常:{e}")
        
return False

def main():
    proxies = fetch_proxies()
    tasks = []
   
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        
for i in range(SUBMIT_TIMES):
            phone, token = TOKEN_PAIRS[i % len(TOKEN_PAIRS)]
            proxy_ip = proxies[i % len(proxies)]
            tasks.append(executor.submit(submit_task, phone, token, proxy_ip))

        
for future in as_completed(tasks):
            _ = future.result()

# -------------------- 程序入口 --------------------
if __name__ == "__main__":
    print(
f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - 开始执行任务")
    main()




这部分代码通过借鉴人杰大佬的方法进行修改,可直接使用。
cdn_sign.js:


function Compress(data, level) {
    const mapChars = "DGi0YA7BemWnQjCl4+bR3f8SKIF9tUz/xhr2oEOgPpac=61ZqwTudLkM5vHyNXsVJ";

    if (data === null) return "";

    let dictionary = {},
        newSequence = {},
        currentSequence = "",
        dictSize = 2,
        bitsUsed = 3,
        codeWidth = 2,
        output = [],
        bitBuffer = 0,
        bitCount = 0;

    const pushBits = (charCode, length) => {
        for (let j = 0; j < length; j++) {
            bitBuffer = (bitBuffer << 1) | (1 & charCode);
            if (bitCount === level - 1) {
                output.push(mapChars.charAt(bitBuffer));
                bitBuffer = 0;
                bitCount = 0;
            } else {
                bitCount++;
            }
            charCode >>= 1;
        }
    };

    for (let i = 0; i < data.length; i++) {
        const currentChar = data.charAt(i);
        if (!dictionary.hasOwnProperty(currentChar)) {
            dictionary[currentChar] = bitsUsed++;
            newSequence[currentChar] = true;
        }
        const combined = currentSequence + currentChar;
        if (dictionary.hasOwnProperty(combined)) {
            currentSequence = combined;
        } else {
            if (newSequence.hasOwnProperty(currentSequence)) {
                if (currentSequence.charCodeAt(0) < 256) {
                    pushBits(0, codeWidth);
                    pushBits(currentSequence.charCodeAt(0), 8);
                } else {
                    pushBits(1, codeWidth);
                    pushBits(currentSequence.charCodeAt(0), 16);
                }
                dictSize--;
                if (dictSize === 0) {
                    dictSize = 1 << codeWidth++;
                }
                delete newSequence[currentSequence];
            } else {
                pushBits(dictionary[currentSequence], codeWidth);
            }
            dictSize--;
            if (dictSize === 0) {
                dictSize = 1 << codeWidth++;
            }
            dictionary[combined] = bitsUsed++;
            currentSequence = currentChar;
        }
    }

    if (currentSequence !== "") {
        if (newSequence.hasOwnProperty(currentSequence)) {
            if (currentSequence.charCodeAt(0) < 256) {
                pushBits(0, codeWidth);
                pushBits(currentSequence.charCodeAt(0), 8);
            } else {
                pushBits(1, codeWidth);
                pushBits(currentSequence.charCodeAt(0), 16);
            }
            dictSize--;
            if (dictSize === 0) {
                dictSize = 1 << codeWidth++;
            }
            delete newSequence[currentSequence];
        } else {
            pushBits(dictionary[currentSequence], codeWidth);
        }
        dictSize--;
        if (dictSize === 0) {
            dictSize = 1 << codeWidth++;
        }
    }

    pushBits(2, codeWidth);
    while (true) {
        bitBuffer <<= 1;
        if (bitCount === level - 1) {
            output.push(mapChars.charAt(bitBuffer));
            break;
        }
        bitCount++;
    }

    return output.join("");
}

function get_sig(data) {
    data = encodeURIComponent(data);
    let chars = 0;
    for (let i = 0; i < data.length; i++) {
        chars = (chars << 7) - chars + 398 + data.charCodeAt(i);
        chars |= 0;
    }
    return chars;
}

function get_ua(data, noPad) {
    if (null == data) return "";
    let res = Compress(data, 6);
    if (noPad) return res;

    switch (res.length % 4) {
        case 0: return res;
        case 1: return res + "===";
        case 2: return res + "==";
        case 3: return res + "=";
    }
}

function parseUrl(url) {
    const urlPattern = /^(https?:\/\/)?([^\/?#]+)([^?#]*)(\?[^#]*)?(#.*)?$/;
    const matches = url.match(urlPattern);

    if (!matches) throw new Error('Invalid URL');

    const searchParams = {};
    if (matches[4]) {
        matches[4].substring(1).split('&').forEach(param => {
            const [key, value] = param.split('=');
            searchParams[key] = value;
        });
    }
    if (matches[1]) {
        matches[1] = matches[1].replace('//', '');
    }
    return {
        protocol: matches[1] || '',
        host: matches[2] || '',
        pathname: matches[3] || '',
        search: matches[4] || '',
        searchParams: searchParams,
        hash: matches[5] || '',
        toString: function () {
            return `${this.protocol}//${this.host}${this.pathname}${this.search}${this.hash}`;
        }
    };
}

function get_cdn_seaech(url, Data) {
    let Obj = parseUrl(url);
    let search = '';
    if (Obj.search) {
        let queryData = Obj.search.replace("?", "").split("&");
        search = queryData.filter(v => !v.startsWith("refer__1972")).join("&") || "";
        if (Obj.search !== "") Obj.search = "?" + search;
    }

    let signText = Obj.toString();
    if (Data) signText += JSON.stringify(Data);
    signText = get_sig(signText) + "|0|" + new Date().getTime() + "|1";

    let keyName = (function () {
        const keyNames = ["type__", "refer__", "ipcity__", "md5__", "decode__", "encode__", "time__", "timestamp__", "type__"];
        let codes = 0;
        for (let i = 0; i < Obj.host.length; i++) {
            codes += Obj.host.charCodeAt(i);
        }
        return keyNames[codes % keyNames.length] + (codes % 10000);
    })();

    let ua = get_ua(signText, true);
    if (!Obj.search) {
        Obj.search = `?${keyName}=` + encodeURIComponent(ua);
    } else {
        Obj.search += `&${keyName}=` + encodeURIComponent(ua);
    }

    return Obj.toString();
}


[size=13.0667px]

[size=13.0667px]

[size=13.0667px]


结帖率:100% (39/39)

签到天数: 19 天

发表于 前天 20:03 | 显示全部楼层   四川省成都市
666666666666666
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表