模仿抖音用户ID加密ID的算法MB4E,提高自己平台ID安全性
先看抖音的格式 对ID加密的格式 MB4EENgLILJPeQKhJht-rjcc6y0ECMk_RGTceg6JBAA=
需求是 同一个ID 比如 413884936367560 每次获取得到的加密ID都是不同的,最终解密的ID都是413884936367560
注意这是一个加密后可解密原文的方式,不是单向加密
那么如下进行一个模仿。目前拆测 固定前缀MB4E和后缀BAA= 这俩要么和机房有关 要么就是和场景有关的一个标识性设置。
下面分别由Python和golang进行实现
记的安装 pip install pycryptodome
from Cryptodome.Cipher import AES
import base64
import os# 固定前缀和后缀 这俩要么和机房有关 要么就是和场景有关的一个标识性设置
PREFIX = "MB4EE"
SUFFIX = "BAA="# 密钥(假设为16字节)
KEY = b'1234567890123456'def pad(data):# PKCS7 填充padding_len = 16 - (len(data) % 16)return data + bytes([padding_len] * padding_len)def unpad(data):# 去除 PKCS7 填充return data[:-data[-1]]def encrypt_id(user_id):# 生成随机IV(16字节)iv = os.urandom(16)# 创建AES加密器cipher = AES.new(KEY, AES.MODE_CFB, iv)# 加密用户IDuser_id_bytes = user_id.to_bytes((user_id.bit_length() + 7) // 8, 'big')padded_user_id = pad(user_id_bytes)encrypted_id = cipher.encrypt(padded_user_id)# 将IV和加密结果编码为URL安全的Base64encoded_id = base64.urlsafe_b64encode(iv + encrypted_id).decode('utf-8')# 去除编码结果中的填充字符 '='encoded_id = encoded_id.rstrip('=')# 添加固定前缀和后缀sec_user_id = PREFIX + encoded_id + SUFFIXreturn sec_user_iddef decrypt_id(sec_user_id):# 去除固定前缀和后缀encoded_id = sec_user_id[len(PREFIX):-len(SUFFIX)]# 解码URL安全的Base64,并手动添加填充字符 '='padding_len = 4 - (len(encoded_id) % 4)encoded_id += '=' * padding_len# 解码Base64decoded_id = base64.urlsafe_b64decode(encoded_id)# 提取IV和加密结果iv = decoded_id[:16]encrypted_id = decoded_id[16:]# 创建AES解密器cipher = AES.new(KEY, AES.MODE_CFB, iv)# 解密用户IDpadded_user_id = cipher.decrypt(encrypted_id)user_id_bytes = unpad(padded_user_id)user_id = int.from_bytes(user_id_bytes, 'big')return user_id# 示例
user_id = 413884936367560
sec_user_id = encrypt_id(user_id)
print(f"Encrypted ID: {sec_user_id}")decrypted_id = decrypt_id(sec_user_id)
print(f"Decrypted ID: {decrypted_id}")
运行结果如下


go语言的实现
package mainimport ("crypto/aes""crypto/cipher""crypto/rand""encoding/base64""encoding/binary""errors""fmt""io""strings"
)// 固定前缀和后缀
const (PREFIX = "MB4EE"SUFFIX = "BAA="
)// 密钥(假设为16字节)
var key = []byte("1234567890123456")// 填充数据
func pad(data []byte) []byte {padding := aes.BlockSize - len(data)%aes.BlockSizepadtext := make([]byte, padding)for i := range padtext {padtext[i] = byte(padding)}return append(data, padtext...)
}// 去除填充数据
func unpad(data []byte) ([]byte, error) {length := len(data)unpadding := int(data[length-1])if unpadding > length {return nil, errors.New("unpad error. This could happen when incorrect encryption key is used")}return data[:(length - unpadding)], nil
}// 加密用户ID
func encryptID(userID int64) (string, error) {// 生成随机IV(16字节)iv := make([]byte, aes.BlockSize)if _, err := io.ReadFull(rand.Reader, iv); err != nil {return "", err}// 创建AES加密器block, err := aes.NewCipher(key)if err != nil {return "", err}// 加密用户IDuserIDBytes := make([]byte, 8)binary.BigEndian.PutUint64(userIDBytes, uint64(userID))paddedUserID := pad(userIDBytes)ciphertext := make([]byte, len(paddedUserID))mode := cipher.NewCFBEncrypter(block, iv)mode.XORKeyStream(ciphertext, paddedUserID)// 将IV和加密结果编码为URL安全的Base64encodedID := base64.URLEncoding.EncodeToString(append(iv, ciphertext...))// 去除编码结果中的填充字符 '='encodedID = strings.TrimRight(encodedID, "=")// 添加固定前缀和后缀secUserID := PREFIX + encodedID + SUFFIXreturn secUserID, nil
}// 解密用户ID
func decryptID(secUserID string) (int64, error) {// 去除固定前缀和后缀encodedID := secUserID[len(PREFIX) : len(secUserID)-len(SUFFIX)]// 解码URL安全的Base64,并手动添加填充字符 '='paddingLen := 4 - len(encodedID)%4encodedID += strings.Repeat("=", paddingLen)// 解码Base64decodedID, err := base64.URLEncoding.DecodeString(encodedID)if err != nil {return 0, err}// 提取IV和加密结果iv := decodedID[:aes.BlockSize]ciphertext := decodedID[aes.BlockSize:]// 创建AES解密器block, err := aes.NewCipher(key)if err != nil {return 0, err}// 解密用户IDmode := cipher.NewCFBDecrypter(block, iv)mode.XORKeyStream(ciphertext, ciphertext)paddedUserID, err := unpad(ciphertext)if err != nil {return 0, err}// 转换为int64userID := int64(binary.BigEndian.Uint64(paddedUserID))return userID, nil
}func main() {userID := int64(66015130374)secUserID, err := encryptID(userID)if err != nil {fmt.Println("Encrypt error:", err)return}fmt.Println("Encrypted ID:", secUserID)decryptedID, err := decryptID(secUserID)if err != nil {fmt.Println("Decrypt error:", err)return}fmt.Println("Decrypted ID:", decryptedID)
}
运行结果如下

相关文章:
模仿抖音用户ID加密ID的算法MB4E,提高自己平台ID安全性
先看抖音的格式 对ID加密的格式 MB4EENgLILJPeQKhJht-rjcc6y0ECMk_RGTceg6JBAA 需求是 同一个ID 比如 413884936367560 每次获取得到的加密ID都是不同的,最终解密的ID都是413884936367560 注意这是一个加密后可解密原文的方式,不是单向加密 那么如下进行…...
solidwork镜像实体
效果如下: 可以看到这两条线是对称的。 第一步,点击这条要镜像的边,接着点击镜像实体。 然后选择镜像轴,即可...
第6天:趋势轮动策略开发(年化18.8%,大小盘轮动加择时)
原创内容第655篇,专注量化投资、个人成长与财富自由。 轮动策略是一种投资策略,它涉及在不同的资产类别、行业或市场之间进行切换,以捕捉市场机会并优化投资组合的表现。 这种策略的核心在于识别并利用不同资产或市场的相对强弱,…...
米客方德SD NAND 掉电测试
SD NAND 异常上下电测试的作用 SD NAND 异常上下电测试是一项关键的测试步骤,对确保SD NAND在不同电源条件下的稳定性和可靠性至关重要。 通过模拟正常和异常电源情况,测试可以验证设备的电源管理功能、检测潜在错误和异常行为,并评估设备在…...
深入探索Android开发之Kotlin核心技术学习大全
Android作为全球最流行的移动操作系统之一,其开发技能的需求日益增长。本文将为您介绍一套专为Android开发者设计的Kotlin核心技术学习资料,包括详细的学习大纲、PDF文档、源代码以及配套视频教程,帮助您从Kotlin基础到高级特性,再…...
langchain报错记录(js)
文章目录 [ERR_PACKAGE_PATH_NOT_EXPORTED]报错:报错语句:思路:解决方法: [ERR_PACKAGE_PATH_NOT_EXPORTED] 报错: Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath ‘./dist/prompts/’ is not defined by…...
VSCode调试Unity准备工作
一.Unity设置VSCode为默认编辑器 Unity编辑器中Edit-Preferences-External Tools中选择VSCode 二.VSCode安装Unity插件 三.Unity的Visual Studio Editor升至最新 Window->Package Manager->Visual Studio Editor 四.下载配置.Net 8.0 安装之前VSCode会提示你下载.Net …...
缓存穿透 问题(缓存空对象)
文章目录 1、缓存穿透2、缓存空对象3、AlbumInfoApiController --》getAlbumInfo()4、AlbumInfoServiceImpl --》getAlbumInfo()5、RedisConstant6、请求缓存不存在的数据 1、缓存穿透 2、缓存空对象 3、AlbumInfoApiController --》getAlbumInfo() GetMapping("getAlbumI…...
Vue3:mitt实现组件通信
目录 一.性质 1.轻量级 2.单例 3.异步 4.事件绑定与解绑 二.作用 1.组件间通信 2.解耦 3.状态管理 4.事件的集中处理 三.使用 1.安装mitt 2.引入mitt;调用mitt;暴露mitt 3.组件1 4.组件2 四.代码 1.组件1 2.组件2 五.效果 一.性质 1…...
一个有个性的使用工具thefuck@Ubuntu
这个工具名字可能有些粗鄙,不过真的有让人眼前一亮的功能。 当用户输入错误的命令时,TheFuck会根据上下文自动推测并给出正确的命令建议。 安装 apt update apt search thefuck apt install thefuck 使用 在错误命令下面直接输入thefuck即可。 不过…...
【PyQt5】PyQt5桌面APP开发学习
跟我学习PyQt5之每天一更 1、兴趣是最好的坚持2、object基类3、QWidget子类 等我不更新了,就说明我学习完成了,有想学而又不会的可以催更留言! 1、兴趣是最好的坚持 看视频看书不如先来一个游戏玩一玩,学习由对他有兴趣开始 2024…...
JdbcTemplate常用方法一览AG网页参数绑定与数据寻址实操
JdbcTemplate是Spring框架中的一个重要组件,主要用于简化JDBC数据库操作。它提供了许多常用的方法,如查询、插入、更新、删除等。本文将介绍JdbcTemplate的常用方法及其使用方式,以及参数绑定和删除数据的方法。 一、JdbcTemplate常用方法 查…...
向日葵好用吗?4款稳定的远程控制软件推荐。
远程控制技术现在已经被应用于很多个领域,像企业办公,远程协助,智能家居,工业控制等等。我们常常会用到的时前两种。而实现远程控制的方式也有多种,但是最方便高效的还是使用第三方软件。我最常使用的是向日葵…...
【开源大模型生态9】百度的文心大模型
这张图展示了百度千帆大模型平台的功能架构及其与BML-AI开发平台和百度百舸AI异构计算平台的关系。以下是各个模块的解释: 模型广场: 通用大模型:提供基础的自然语言处理能力。行业大模型:针对不同行业的定制化模型。大模型工具链…...
CSS的三种基本选择器
使用CSS控制网页格式有行内法,内嵌式,链接式,导入式等方法 这里将采用内嵌式的方法书写 内嵌法就是通过<style>标记将样式定义在HTML的文件头部中 1.标记选择器 标记选择器特点:定义了标记选择器之后,网页中…...
排序学习笔记
目录 排序排序的相关概念冒泡排序插入排序选择排序堆排序快速排序归并排序 内排序和外排序非比较排序稳定性稳定性 完 排序 排序的相关概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起…...
【nginx】缓存配置文件
http {# ... 其他配置 ...# 缓存目录配置proxy_cache_path /var/cache/nginx/proxy_cache levels1:2 keys_zonemy_cache:10m inactive60m use_temp_pathoff;# ... 其他配置 ... }server {listen 80;server_name www.example.com;location / {root /var/www/example.com/public;…...
如何使用 maxwell 同步到 redis?
文章目录 1、MaxwellListener2、MxwObject1. 使用Maxwell捕获MySQL变更2. 将Maxwell的输出连接到消息系统3. 从消息系统读取数据并同步到Redis注意事项 1、MaxwellListener package com.atguigu.tingshu.album.listener;import com.alibaba.fastjson.JSON; import org.apache.…...
C++ 元编程
目录 C 元编程1. 术语2. 元函数1. 数值元函数示例:阶乘计算 2. 类型元函数示例:类型选择 3. 混合编程1. 常规的计算点积范例2. 混合元编程计算点积 4. typelist实现设计和基本操作接口(算法)完整代码 5. tuple 实现基础知识1. 左值…...
运行npm install 时,卡在sill idealTree buildDeps没有反应
一直停留在sill idealTree buildDeps 解决方法 npm config set registry https://registry.npm.taobao.org 配置后用下面命令看是否配置成功 npm config get registry 如果配置还不好使 就执行下行的ssl npm set strict-ssl false 然后执行 npm install 成功执行...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
数据库——redis
一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...
Axure Rp 11 安装、汉化、授权
Axure Rp 11 安装、汉化、授权 1、前言2、汉化2.1、汉化文件下载2.2、windows汉化流程2.3、 macOs汉化流程 3、授权 1、前言 Axure Rp 11官方下载链接:https://www.axure.com/downloadthanks 2、汉化 2.1、汉化文件下载 链接: https://pan.baidu.com/s/18Clf…...
