easily-openJCL 要尝试下用 显卡 做数据对称加密吗?
开源技术栏
本文演示了一个案例,使用显卡进行数据加密哦,加密方法是 XOR
目录
文章目录
- easily-openJCL 要尝试下用 显卡 做数据对称加密吗?
- 目录
- 开始
- 导入项目库
- 加密操作
- 解密操作
- 性能如何
开始
导入项目库
从 1.0.3 版本之后,easily-openJCL 支持了 XOR
的加密与解密操作,我们可以直接引入此版本的依赖库文件,下面是坐标!
<dependencies>
<!-- https://mvnrepository.com/artifact/io.github.BeardedManZhao/easily-openJCL -->
<dependency>
<groupId>io.github.BeardedManZhao</groupId>
<artifactId>easily-openJCL</artifactId>
<version>1.0.3</version>
</dependency>
</dependencies>
加密操作
package org.example;
import io.github.BeardedManZhao.easilyJopenCL.EasilyOpenJCL;
import io.github.BeardedManZhao.easilyJopenCL.MemSpace;
import io.github.BeardedManZhao.easilyJopenCL.kernel.LengthKernelSource;
import org.jocl.Pointer;
import org.jocl.Sizeof;
public class Main {
public static void main(String[] args0) {
// 准备一个 easilyOpenJCL 操作对象
final EasilyOpenJCL easilyOpenJCL = EasilyOpenJCL.initOpenCLEnvironment(
// 为对象装载两个计算组件 分别是 XOR 加密和解密使用的组件
LengthKernelSource.ARRAY_ENCODE_XOR_ARRAY_CHAR2,
LengthKernelSource.ARRAY_DECODE_XOR_ARRAY_CHAR2
);
// 准备两个 char 数组 a b 分别代表的是被加密的数据和加密使用的密钥
final char[] a = "this is a data!!!".toCharArray(), b = "349567456456".toCharArray();
// 准备一个数值 代表结果的长度 需要在内存空间对象中设置,用来开辟内存
final long resLen = a.length;
// 使用内存空间对象将 a 和 b 进行封装
MemSpace memSpace = easilyOpenJCL.createMemSpace(
// 两个 char 数组的指针,用来读取数据
Pointer.to(a), Pointer.to(b),
// 两个指针的空间 以及 结果需要的空间 还有每个元素需要的字节数
a.length, b.length, resLen, Sizeof.cl_char2,
// 指定当前内存空间要用来做哪个计算 这里是加密
LengthKernelSource.ARRAY_ENCODE_XOR_ARRAY_CHAR2
);
// 调用 easilyOpenJCL 开始操作加密任务
easilyOpenJCL.calculate(bf -> {
for (int i = 0; i < resLen; i++) {
// 在这里打印出来加密的结果 为了避免出现不可识别的字符,直接转换成数值
System.out.print((int) bf.getChar(i * Sizeof.cl_char2) + " ");
}
}, memSpace, true);
}
}
上面代码的计算结果如下所示!其中每个数值都是一个字符的 ASCII 形式
71 92 80 70 22 94 71 21 87 20 81 87 71 85 24 20 23
解密操作
在上面我们已经对于一个字符串进行了加密操作,并将加密之后的每个字符的ASCII统计了出来,下面我们要对加密之后的 71 92 80 70 22 94 71 21 87 20 81 87 71 85 24 20 23
进行 解密操作。
package org.example;
import io.github.BeardedManZhao.easilyJopenCL.EasilyOpenJCL;
import io.github.BeardedManZhao.easilyJopenCL.MemSpace;
import io.github.BeardedManZhao.easilyJopenCL.kernel.LengthKernelSource;
import org.jocl.Pointer;
import org.jocl.Sizeof;
public class Main {
public static void main(String[] args0) {
// 准备加密之后的数据
char[] chars = {71, 92, 80, 70, 22, 94, 71, 21, 87, 20, 81, 87, 71, 85, 24, 20, 23};
// 准备解密的密钥 需要和加密的一致,否则解析之后就不同了
char[] key = "349567456456".toCharArray();
// 设置解密之后的数组长度,应该是和 chars 一致!
final long l = chars.length;
// 准备一个 easilyOpenJCL 操作对象
final EasilyOpenJCL easilyOpenJCL = EasilyOpenJCL.initOpenCLEnvironment(
// 为对象装载两个计算组件 分别是 XOR 加密和解密使用的组件
LengthKernelSource.ARRAY_ENCODE_XOR_ARRAY_CHAR2,
LengthKernelSource.ARRAY_DECODE_XOR_ARRAY_CHAR2
);
// 封装内存空间 解密时候的操作数分别是 加密之后的数据chars 以及 加密时使用的key
MemSpace memSpace = easilyOpenJCL.createMemSpace(
Pointer.to(chars), Pointer.to(key),
chars.length, key.length, l, Sizeof.cl_char2,
LengthKernelSource.ARRAY_DECODE_XOR_ARRAY_CHAR2
);
// 直接开始解密操作
easilyOpenJCL.calculate(byteBuffer -> {
for (int i = 0; i < l; i++) {
System.out.print(byteBuffer.getChar(i * Sizeof.cl_char2));
}
}, memSpace, true);
}
}
在下面就是计算结果,可以看到它成功的将数据还原了出来!
this is a data!!!
性能如何
使用 GPU 进行加密操作,相较于CPU,速度会快许多,下面是我们的一个基准测试代码,以及测试结果,其将非常庞大的字符数组进行了加密和解密操作!
CPU | GPU |
---|---|
i7-12700 | RX550 |
有趣的是,GPU远远落后于CPU工艺的情况下,CPU的计算速度比 GPU 的慢