|
下面是LUA版本的:
[Lua] 纯文本查看 复制代码 -------------------------------------------------------
-- 文件名 : encypt_001.lua
-- 说 明 : 加密公式001, 根据UID进行交换移位运算
-- 版 本 : V1.2 2021-12-24
-- Copyright (C), 2020-2030, 安富莱电子 [url]www.armfly.com[/url]
-------------------------------------------------------
--UID加密函数,传入uid 和 rnd(随机数)
--uid和_rnd格式为二进制字符串
-- & 按位与
-- | 按位或
-- ~ 按位异或
-- >> 右移
-- << 左移
-- ~ 按位非
-- % 取模
-- ^ 乘方
-- - 取负
--A1 - A16 参数由PC软件配置后,将覆盖如下的初值
A1 = 1
A2 = 2
A3 = 3
A4 = 3
A5 = 4
A6 = 5
A7 = 6
A8 = 8
A9 = 9
A10 = 10
A11 = 11
A12 = 12
A13 = 13
A14 = 14
A15 = 15
A16 = 16
--调试加密函数的方法:
--print_hex(encrypt("\x12\x34\x56\x78\x90\x12", "1234"))
--_rnd : 算法函数第2个形参随机数。 如果使用,需要将它保存到FLASH
function encrypt(_uid, _rnd)
local uid = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}
local rnd = {}
local out = {}
local s
local i
local j
--将二进制的字符串转换为整数字节数组
if (_uid == nil) then
return
end
--#_uid表示字符串的长度。转换到整数数组存放
for i = 1,#_uid,1 do
uid[i] = tonumber(string.byte(_uid, i,i))
end
--补齐16字节(不足16字节的循环取值)
j = 1
for i = #_uid+1,16,1 do
uid[i] = uid[j]
j = j+1
end
if (_rnd ~= nil) then
for i = 1,#_rnd,1 do
rnd[i] = tonumber(string.byte(_rnd, i,i))
end
end
--进行逻辑运算 用户可自行修改为保密算法
out[1] = uid[A1] ~ (uid[A2] >> 1) ~ (uid[A3] >> 1)
out[2] = uid[A4] ~ (uid[A5] >> 0) ~ (uid[A6] >> 1)
out[3] = uid[A7] ~ (uid[A8] >> 1) ~ (uid[A9] >> 3)
out[4] = uid[A10] ~ (uid[A11] >> 2) ~ (uid[A12] >> 0)
out[5] = uid[A1] ~ (uid[A10] << 1) ~ (uid[A2] >> 0)
out[6] = uid[A4] ~ (uid[A7] << 1) ~ (uid[A5] << 2)
out[7] = uid[A7] ~ (uid[A4] >> 0) ~ (uid[A8] << 0)
out[8] = uid[A10] ~ (uid[A1] >> 2) ~ (uid[A11] << 1)
out[9] = uid[A2] ~ (uid[A10] >> 1)
out[10] = uid[A3] ~ (uid[A7] << 1)
out[11] = uid[A6] ~ (uid[A4] << 1)
out[12] = uid[A9] ~ (uid[A1] >> 2)
out[13] = uid[A1] ~ (uid[A2] >> 1)
out[14] = uid[A3] ~ (uid[A5] >> 0)
out[15] = uid[A6] ~ (uid[A8] << 2)
out[16] = uid[A9] ~ (uid[A11] >> 0)
--和随机数进行异或
for i = 1,#out,1 do
out[i] = out[i] ~ rnd[((i - 1) % #rnd) + 1]
end
--拼接为二进制串返回(固定16字节,存储时可以只保存4,8,12,16字节
s = string.char(out[1] & 0xFF)
s = s..string.char(out[2] & 0xFF)
s = s..string.char(out[3] & 0xFF)
s = s..string.char(out[4] & 0xFF)
s = s..string.char(out[5] & 0xFF)
s = s..string.char(out[6] & 0xFF)
s = s..string.char(out[7] & 0xFF)
s = s..string.char(out[8] & 0xFF)
s = s..string.char(out[9] & 0xFF)
s = s..string.char(out[10] & 0xFF)
s = s..string.char(out[11] & 0xFF)
s = s..string.char(out[12] & 0xFF)
s = s..string.char(out[13] & 0xFF)
s = s..string.char(out[14] & 0xFF)
s = s..string.char(out[15] & 0xFF)
s = s..string.char(out[16] & 0xFF)
return s
end
---------------------------结束-----------------------------------
下面是Copilot的生成:
[C] 纯文本查看 复制代码 #include <stdio.h>
#include <stdint.h>
#include <string.h>
#define A1 1
#define A2 2
#define A3 3
#define A4 3
#define A5 4
#define A6 5
#define A7 6
#define A8 8
#define A9 9
#define A10 10
#define A11 11
#define A12 12
#define A13 13
#define A14 14
#define A15 15
#define A16 16
void encrypt(const uint8_t* _uid, const uint8_t* _rnd, uint8_t* out) {
uint8_t uid[16] = {0};
uint8_t rnd[16] = {0};
int i, j;
if (_uid == NULL) {
return;
}
// Convert binary string to integer byte array
for (i = 0; i < strlen((const char*)_uid); i++) {
uid[i] = _uid[i];
}
// Pad to 16 bytes (loop values if less than 16 bytes)
j = 0;
for (i = strlen((const char*)_uid); i < 16; i++) {
uid[i] = uid[j++];
}
if (_rnd != NULL) {
for (i = 0; i < strlen((const char*)_rnd); i++) {
rnd[i] = _rnd[i];
}
}
// Perform logical operations
out[0] = uid[A1 - 1] ^ (uid[A2 - 1] >> 1) ^ (uid[A3 - 1] >> 1);
out[1] = uid[A4 - 1] ^ (uid[A5 - 1] >> 0) ^ (uid[A6 - 1] >> 1);
out[2] = uid[A7 - 1] ^ (uid[A8 - 1] >> 1) ^ (uid[A9 - 1] >> 3);
out[3] = uid[A10 - 1] ^ (uid[A11 - 1] >> 2) ^ (uid[A12 - 1] >> 0);
out[4] = uid[A1 - 1] ^ (uid[A10 - 1] << 1) ^ (uid[A2 - 1] >> 0);
out[5] = uid[A4 - 1] ^ (uid[A7 - 1] << 1) ^ (uid[A5 - 1] << 2);
out[6] = uid[A7 - 1] ^ (uid[A4 - 1] >> 0) ^ (uid[A8 - 1] << 0);
out[7] = uid[A10 - 1] ^ (uid[A1 - 1] >> 2) ^ (uid[A11 - 1] << 1);
out[8] = uid[A2 - 1] ^ (uid[A10 - 1] >> 1);
out[9] = uid[A3 - 1] ^ (uid[A7 - 1] << 1);
out[10] = uid[A6 - 1] ^ (uid[A4 - 1] << 1);
out[11] = uid[A9 - 1] ^ (uid[A1 - 1] >> 2);
out[12] = uid[A1 - 1] ^ (uid[A2 - 1] >> 1);
out[13] = uid[A3 - 1] ^ (uid[A5 - 1] >> 0);
out[14] = uid[A6 - 1] ^ (uid[A8 - 1] << 2);
out[15] = uid[A9 - 1] ^ (uid[A11 - 1] >> 0);
// XOR with random number
for (i = 0; i < 16; i++) {
out[i] ^= rnd[i % strlen((const char*)_rnd)];
}
}
void to_binary_string(const uint8_t* out, char* s) {
for (int i = 0; i < 16; i++) {
sprintf(s + i * 2, "%02X", out[i]);
}
}
int main() {
uint8_t uid[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0x12};
uint8_t rnd[] = "1234";
uint8_t out[16];
char s[33] = {0}; // 32 characters for 16 bytes + 1 for null terminator
encrypt(uid, rnd, out);
to_binary_string(out, s);
printf("%s\n", s);
return 0;
}
然后我根据我自己的板子,简单修改,直接可以使用了,确实非常方便
[C] 纯文本查看 复制代码 #include <stdio.h>
#include <stdlib.h>
#include "stdint.h"
#include <string.h>
/*
*********************************************************************************************************
* 定义
*********************************************************************************************************
*/
typedef struct {
uint32_t enable; // 使能位
uint32_t address; // 存储地址
uint32_t length; // 随机数长度
} RNG_TAB_t;
uint8_t UidArray[16] = {0};
uint8_t EncryptUidArray[16] = {0};
uint8_t ReEncryptUidArray[16] = {0};
/*
*********************************************************************************************************
* 通过上位机更新,与上位机保持一致
*********************************************************************************************************
*/
#define A1 1
#define A2 2
#define A3 3
#define A4 4
#define A5 5
#define A6 6
#define A7 7
#define A8 8
#define A9 9
#define A10 10
#define A11 11
#define A12 12
#define A13 13
#define A14 14
#define A15 15
#define A16 16
#define ENCRYPT_ADDR 0x08100000 //UID加密数据存储地址
#define ENCRYPT_LEN 8 //UID加密数据长度
#define UID_ADDR 0x1FF1E800 //MCU UID地址
#define UID_BYTES 12 //MCU UID字节数
#define ENCRYPT_RND_IDX 0 //加密用初值选择 0:固定数,1-4是随机数
RNG_TAB_t RNG_TAB[] = { //随机数
{1, 0x0800001c, 4},
{0, 0x08000000, 4},
{0, 0x08000000, 4},
{0, 0x08000000, 4}
};
uint8_t RNG_CONST_DATA[] = "01 02 03 04 05 06 07 56"; //常量值
/*
*********************************************************************************************************
* UID相关API
*********************************************************************************************************
*/
static uint8_t stringToHexArray(const char *str, uint8_t *hexArray)
{
uint32_t index = 0;
while (*str != '\0')
{
while (*str == ' ')
{
str++;
}
if (*str == '\0')
{
break;
}
sscanf(str, "%2hhx", &hexArray[index++]);
str += 2;
}
return index;
}
/*
*********************************************************************************************************
* 函 数 名: encrypt
* 功能说明: 计算UID加密
* 形 参: ---
* 返 回 值: 无
*********************************************************************************************************
*/
static void encrypt(const uint8_t* _uid, const uint8_t* _rnd, uint8_t _rndsize, uint8_t* out)
{
uint8_t uid[16] = {0};
uint8_t rnd[16] = {0};
int i, j;
if (_uid == NULL)
{
return;
}
for (i = 0; i < UID_BYTES; i++)
{
uid[i] = _uid[i];
}
j = 0;
for (i = UID_BYTES; i < 16; i++)
{
uid[i] = uid[j++];
}
if (_rnd != NULL)
{
for (i = 0; i < _rndsize; i++)
{
rnd[i] = _rnd[i];
}
}
out[0] = uid[A1 - 1] ^ (uid[A2 - 1] >> 1) ^ (uid[A3 - 1] >> 1);
out[1] = uid[A4 - 1] ^ (uid[A5 - 1] >> 0) ^ (uid[A6 - 1] >> 1);
out[2] = uid[A7 - 1] ^ (uid[A8 - 1] >> 1) ^ (uid[A9 - 1] >> 3);
out[3] = uid[A10 - 1] ^ (uid[A11 - 1] >> 2) ^ (uid[A12 - 1] >> 0);
out[4] = uid[A1 - 1] ^ (uid[A10 - 1] << 1) ^ (uid[A2 - 1] >> 0);
out[5] = uid[A4 - 1] ^ (uid[A7 - 1] << 1) ^ (uid[A5 - 1] << 2);
out[6] = uid[A7 - 1] ^ (uid[A4 - 1] >> 0) ^ (uid[A8 - 1] << 0);
out[7] = uid[A10 - 1] ^ (uid[A1 - 1] >> 2) ^ (uid[A11 - 1] << 1);
out[8] = uid[A2 - 1] ^ (uid[A10 - 1] >> 1);
out[9] = uid[A3 - 1] ^ (uid[A7 - 1] << 1);
out[10] = uid[A6 - 1] ^ (uid[A4 - 1] << 1);
out[11] = uid[A9 - 1] ^ (uid[A1 - 1] >> 2);
out[12] = uid[A1 - 1] ^ (uid[A2 - 1] >> 1);
out[13] = uid[A3 - 1] ^ (uid[A5 - 1] >> 0);
out[14] = uid[A6 - 1] ^ (uid[A8 - 1] << 2);
out[15] = uid[A9 - 1] ^ (uid[A11 - 1] >> 0);
for (i = 0; i < 16; i++)
{
out[i] ^= rnd[i % _rndsize];
}
}
/*
*********************************************************************************************************
* 函 数 名: UidCompare
* 功能说明: 比较加密的UID
* 形 参: 1表示成功,0表示失败
* 返 回 值: 反
*********************************************************************************************************
*/
uint8_t UidCompare(void)
{
uint8_t tempbuf[16] = {0};
uint16_t i;
uint8_t size;
uint8_t index;
for(i = 0; i < UID_BYTES; i++)
{
UidArray[i] = *(volatile uint8_t*)(UID_ADDR+i);
}
for(i = 0; i < ENCRYPT_LEN; i++)
{
EncryptUidArray[i] = *(volatile uint8_t*)(ENCRYPT_ADDR + i);
}
if(ENCRYPT_RND_IDX == 0)
{
size = stringToHexArray((const char *)RNG_CONST_DATA, tempbuf);
encrypt(UidArray, tempbuf, size, ReEncryptUidArray);
}
else
{
index = (uint8_t)(ENCRYPT_RND_IDX - 1);
for(i = 0; i < RNG_TAB[index].length; i++)
{
tempbuf[i] = *((uint8_t *)(uintptr_t)(RNG_TAB[index].address + i));
}
encrypt(UidArray, tempbuf, RNG_TAB[index].length, ReEncryptUidArray);
}
for (i = 0; i < ENCRYPT_LEN; i++)
{
if (ReEncryptUidArray[i] != EncryptUidArray[i])
{
return 0;
}
}
return 1;
}
|
|