安卓实现魔改版 CRC32 算法

版权归作者所有,如有转发,请注明文章出处:cyrus-studio.github.io/blog/

关于 CRC32 算法介绍可以参考这篇文章:常用加解密算法介绍

标准 CRC32 算法

创建 crc32.cpp,使用 C++ 实现标准 CRC32 算法

arduino 复制代码
#include <jni.h>
#include <string>
#include <android/log.h>

#define TAG "CRC32"

unsigned int crc32_table[256];

// 初始化 CRC32 查找表
void init_crc32_table() {
    unsigned int crc;
    for (int i = 0; i < 256; i++) {
        crc = i;
        for (int j = 8; j > 0; j--) {
            if (crc & 1) {
                crc = (crc >> 1) ^ 0xedb88320;
            } else {
                crc >>= 1;
            }
        }
        crc32_table[i] = crc;
    }
}

// 计算 CRC32
unsigned int crc32(const std::string& str) {
    unsigned int crc = 0xffffffff;
    for (size_t i = 0; i < str.size(); i++) {
        unsigned char byte = str[i];
        crc = (crc >> 8) ^ crc32_table[(crc ^ byte) & 0xff];
    }
    return ~crc;
}

kotlin 层声明 native 方法

kotlin 复制代码
package com.cyrus.example.crc32

class CRC32Utils {

    companion object {
        // 加载 native 库
        init {
            System.loadLibrary("crc32")
        }

        // 声明 native 静态方法
        @JvmStatic
        external fun crc32(input: String): String
    }

}

实现 native 方法并调用 crc32 方法进行加密并返回 hex 字符串

scss 复制代码
extern "C" JNIEXPORT jstring JNICALL
Java_com_cyrus_example_crc32_CRC32Utils_crc32(JNIEnv *env, jclass , jstring input) {
    // 初始化 CRC32 表(只需调用一次)
    static bool is_initialized = false;
    if (!is_initialized) {
        init_crc32_table();
        is_initialized = true;
    }

    // 获取输入的字符串
    const char* str = env->GetStringUTFChars(input, nullptr);
    std::string input_str(str);
    env->ReleaseStringUTFChars(input, str);

    // 计算 CRC32 值
    unsigned int crc = crc32(input_str);

    // 返回 CRC32 的十六进制字符串
    char crcHex[9];  // CRC32 是 32 位,最大为 8 位十六进制数
    snprintf(crcHex, sizeof(crcHex), "%08x", crc);
    return env->NewStringUTF(crcHex);
}

调用示例:

arduino 复制代码
CRC32Utils.crc32("txj1Dc")

效果如下:

自定义 Table 版 CRC32 算法

CRC32 Table 是通过 init_crc32_table 方法中 位移 和 异或 常量 0xedb88320 运算得来的

ini 复制代码
crc = (crc >> 1) ^ 0xedb88320;

标准的 CRC32 Table 如下:

复制代码
 0, 0x77073096, 0xEE0E612C, 0x990951BA,
 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D

我们可以通过修改常量值,实现自定义 Table,比如改成 0xd76aa478

c 复制代码
#include <jni.h>
#include <string>
#include <android/log.h>

#define TAG "CustomCRC32"

unsigned int custom_crc32_table[256];

// 初始化 CRC32 查找表
void init_custom_crc32_table() {
    unsigned int crc;
    for (int i = 0; i < 256; i++) {
        crc = i;
        for (int j = 8; j > 0; j--) {
            if (crc & 1) {
                crc = (crc >> 1) ^ 0xd76aa478;
            } else {
                crc >>= 1;
            }
        }
        custom_crc32_table[i] = crc;
    }
}

// 计算 CRC32
unsigned int custom_crc32(const std::string& str) {
    unsigned int crc = 0xffffffff;
    for (size_t i = 0; i < str.size(); i++) {
        unsigned char byte = str[i];
        crc = (crc >> 8) ^ custom_crc32_table[(crc ^ byte) & 0xff];
    }
    return ~crc;
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_cyrus_example_crc32_CRC32Utils_customTableCRC32(JNIEnv *env, jclass , jstring input) {
    // 初始化 CRC32 表(只需调用一次)
    static bool is_initialized = false;
    if (!is_initialized) {
        init_custom_crc32_table();
        is_initialized = true;
    }

    // 获取输入的字符串
    const char* str = env->GetStringUTFChars(input, nullptr);
    std::string input_str(str);
    env->ReleaseStringUTFChars(input, str);

    // 计算 CRC32 值
    unsigned int crc = custom_crc32(input_str);

    // 返回 CRC32 的十六进制字符串
    char crcHex[9];  // CRC32 是 32 位,最大为 8 位十六进制数
    snprintf(crcHex, sizeof(crcHex), "%08x", crc);
    return env->NewStringUTF(crcHex);
}

效果如下:

魔改版 CRC32 算法

魔改逻辑:

  • 修改常量 0xedb88320 改为 0x82F63B78

  • 初始值 0xffffffff 改为 0xDEADBEEF。

  • XOR 0xA5 扰动输入。

  • 右移 7 位,而非 8 位。

  • 计算 CRC 时额外 XOR 0xA5A5A5A5 进一步扰动结果。

c 复制代码
#include <jni.h>
#include <string>
#include <android/log.h>

#define TAG "ModifiedCRC32"

// 魔改版 CRC32 表
unsigned int modified_crc32_table[256];

// 初始化魔改版 CRC32 查找表
void init_modified_crc32_table() {
    for (int i = 0; i < 256; i++) {
        unsigned int crc = i;
        for (int j = 8; j > 0; j--) {
            if (crc & 1) {
                crc = (crc >> 1) ^ 0x82F63B78;
            } else {
                crc >>= 1;
            }
        }
        modified_crc32_table[i] = crc;
    }
}

// 魔改版 CRC32 计算
unsigned int modified_crc32(const std::string& str) {
    unsigned int crc = 0xDEADBEEF;  // 魔改初始值
    for (size_t i = 0; i < str.size(); i++) {
        unsigned char byte = str[i] ^ 0xA5;  // 额外扰动
        crc = ((crc >> 7) ^ modified_crc32_table[(crc ^ byte) & 0xff]) ^ 0xA5A5A5A5; // 变更位移方式 & 额外 XOR 干扰
    }
    return ~crc;
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_cyrus_example_crc32_CRC32Utils_modifiedCRC32(JNIEnv *env, jclass, jstring input) {
    // 初始化 CRC32 表(只需调用一次)
    static bool is_initialized = false;
    if (!is_initialized) {
        init_modified_crc32_table();
        is_initialized = true;
    }

    // 获取输入字符串
    const char* str = env->GetStringUTFChars(input, nullptr);
    std::string input_str(str);
    env->ReleaseStringUTFChars(input, str);

    // 计算魔改版 CRC32
    unsigned int crc = modified_crc32(input_str);

    // 返回十六进制格式的 CRC32 结果
    char crcHex[9];
    snprintf(crcHex, sizeof(crcHex), "%08x", crc);
    return env->NewStringUTF(crcHex);
}

效果如下:

完整源码

完整源码地址:github.com/CYRUS-STUDI...

相关推荐
初级炼丹师(爱说实话版)5 分钟前
算法面经常考题整理(3)大模型
算法
Neil今天也要学习1 小时前
永磁同步电机无速度算法--基于相位超前校正的LESO
算法·1024程序员节
码农多耕地呗1 小时前
力扣226.翻转二叉树(java)
算法·leetcode·职场和发展
消失的旧时光-19431 小时前
Kotlin × Gson:为什么遍历 JsonObject 要用 entrySet()
android·kotlin·数据处理·1024程序员节
G果2 小时前
安卓APP页面之间传参(Android studio 开发)
android·java·android studio
IT古董3 小时前
【第五章:计算机视觉-项目实战之推荐/广告系统】2.粗排算法-(3)理解粗排模型之在线部分:在线架构及对双塔的应用
算法·1024程序员节
大数据张老师3 小时前
数据结构——平衡二叉树
数据结构·算法·查找
py有趣3 小时前
LeetCode算法学习之合并区间
学习·算法·leetcode
m0_748233643 小时前
单调栈详解【C/C++】
c语言·c++·算法·1024程序员节
郝学胜-神的一滴3 小时前
Linux中的`fork`函数详解:深入解析
linux·服务器·开发语言·c++·算法