Flutter for OpenHarmony 三方库实战:使用 crypto-js 构建学习打卡口令摘要生成器
在应用开发中,经常会遇到“把一段文本生成固定摘要”的需求。例如接口签名、数据校验、文件完整性验证、打卡口令生成等场景,都可能需要使用摘要算法。摘要算法不是加密算法。它的作用是把一段输入内容转换成一段固定格式的字符串结果。常见的摘要算法包括 MD5、SHA-1、SHA-256 等。需要注意的是,摘要结果一般不能反向还原出原文。也就是说,SHA-256 不是“把密码加密一下再解密回来”的工具。把摘要算
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
项目效果
本文实现的是一个基于 @ohos/crypto-js 的学习打卡口令摘要生成器。用户可以输入课程名称、学号、打卡日期和自定义口令,点击“生成摘要”按钮后,应用会将这些信息拼接成原始文本,并使用 SHA-256 和 MD5 生成对应的摘要结果。
页面主要包含以下内容:
- 顶部标题:打卡摘要生成器;
- 课程名称输入框;
- 学号输入框;
- 打卡日期输入框;
- 自定义口令输入框;
- 生成摘要按钮;
- 填充示例按钮;
- 清空按钮;
- 原始拼接文本展示;
- SHA-256 摘要结果展示;
- MD5 摘要结果展示;
- 页面整体采用卡片式布局。
这个页面可以作为学习打卡、签到校验、口令摘要、接口签名演示、数据完整性校验等项目的基础版本。
前言
在应用开发中,经常会遇到“把一段文本生成固定摘要”的需求。例如接口签名、数据校验、文件完整性验证、打卡口令生成等场景,都可能需要使用摘要算法。
摘要算法不是加密算法。它的作用是把一段输入内容转换成一段固定格式的字符串结果。常见的摘要算法包括 MD5、SHA-1、SHA-256 等。
需要注意的是,摘要结果一般不能反向还原出原文。也就是说,SHA-256 不是“把密码加密一下再解密回来”的工具。把摘要算法当加解密用,属于开发世界里很经典的自我伤害行为。
本篇文章选择使用 OpenHarmony 三方库 @ohos/crypto-js 来实现文本摘要生成功能。通过该库,可以较方便地对字符串生成 MD5 和 SHA-256 摘要。
本篇文章以“学习打卡口令摘要生成器”为场景,使用课程名称、学号、日期和口令拼接成原始文本,再通过 CryptoJS.SHA256() 和 CryptoJS.MD5() 生成摘要结果,并结合 ArkUI 构建一个完整的工具页面。
一、项目目标
本次实践主要实现以下目标:
- 在 OpenHarmony 项目中安装
@ohos/crypto-js三方库; - 在 ArkTS 页面中引入并使用
CryptoJS; - 使用
TextInput接收打卡信息; - 将课程名称、学号、日期和口令拼接为原始文本;
- 使用 SHA-256 生成摘要结果;
- 使用 MD5 生成摘要结果;
- 展示原始文本和摘要结果;
- 使用 ArkUI 构建卡片式工具页面;
- 实现填充示例、清空内容和状态提示;
- 在 OpenHarmony 模拟器中完成运行验证。
二、技术栈
| 类型 | 内容 |
|---|---|
| 实战方向 | Flutter for OpenHarmony 三方库实战 |
| 实现平台 | OpenHarmony |
| 开发语言 | ArkTS |
| 三方库 | @ohos/crypto-js |
| 使用算法 | SHA-256 / MD5 |
| 功能场景 | 摘要生成 / 打卡口令 / 数据校验 |
| UI 框架 | ArkUI |
| 开发工具 | DevEco Studio |
| 运行环境 | OpenHarmony 模拟器 |
三、为什么选择 crypto-js
在实际项目中,摘要算法经常用于数据校验和签名场景。例如:
- 生成接口签名;
- 校验文本是否被修改;
- 生成打卡口令摘要;
- 对文件内容生成摘要;
- 生成唯一标识辅助字段;
- 校验本地缓存内容;
- 处理简单的数据完整性验证。
如果自己实现 MD5 或 SHA-256 算法,代码复杂度会非常高,也不适合作为普通应用开发中的练习方向。使用成熟的三方库可以减少重复工作,把重点放在业务逻辑和页面实现上。
在本项目中,@ohos/crypto-js 主要用于:
- 对原始打卡文本生成 SHA-256 摘要;
- 对原始打卡文本生成 MD5 摘要;
- 对比不同输入内容生成的摘要变化;
- 演示摘要算法在 OpenHarmony 页面中的基本使用方式。
通过这个项目,可以比较直观地理解 OpenHarmony 中三方加密摘要库的接入方式。
四、安装 crypto-js 三方库
在项目根目录打开终端,执行以下命令:
ohpm install @ohos/crypto-js
安装完成后,可以检查项目中是否出现以下内容:
oh_modules
oh-package-lock.json5
oh-package.json5
如果依赖安装成功,就可以在 ArkTS 页面中引入:
import { CryptoJS } from '@ohos/crypto-js';
本项目主要使用以下方法:
| 方法 | 作用 |
|---|---|
| CryptoJS.SHA256() | 生成 SHA-256 摘要 |
| CryptoJS.MD5() | 生成 MD5 摘要 |
| toString() | 将摘要结果转换成字符串 |
五、项目结构
本次主要修改页面文件即可:
entry
└── src
└── main
└── ets
└── pages
└── Index.ets
如果你的项目中原本已经有 Index.ets,可以直接替换页面内容。
文件说明:
| 文件 | 作用 |
|---|---|
| Index.ets | 页面展示、打卡信息输入、摘要生成和结果渲染 |
本项目不需要请求远程接口,因此不需要配置网络权限。页面中的所有摘要生成操作都在本地完成。
六、页面状态设计
页面中主要使用以下状态变量:
@State courseName: string = '';
@State studentId: string = '';
@State checkDate: string = '';
@State secretCode: string = '';
@State rawText: string = '';
@State sha256Text: string = '';
@State md5Text: string = '';
@State resultText: string = '请输入打卡信息后生成摘要';
@State resultColor: string = '#999999';
字段说明如下:
| 状态变量 | 作用 |
|---|---|
| courseName | 保存课程名称 |
| studentId | 保存学号 |
| checkDate | 保存打卡日期 |
| secretCode | 保存自定义口令 |
| rawText | 保存拼接后的原始文本 |
| sha256Text | 保存 SHA-256 摘要 |
| md5Text | 保存 MD5 摘要 |
| resultText | 保存操作结果提示 |
| resultColor | 控制提示文字颜色 |
七、核心功能设计
本项目的核心流程如下:
- 用户输入课程名称;
- 用户输入学号;
- 用户输入打卡日期;
- 用户输入自定义口令;
- 点击“生成摘要”按钮;
- 将四项内容拼接成原始文本;
- 使用 SHA-256 生成摘要;
- 使用 MD5 生成摘要;
- 将原始文本和摘要结果展示到页面中。
原始文本拼接格式如下:
课程名称|学号|打卡日期|自定义口令
例如:
OpenHarmony应用开发|20260001|2026-05-11|study-hard
生成摘要的核心代码如下:
this.sha256Text = CryptoJS.SHA256(text).toString();
this.md5Text = CryptoJS.MD5(text).toString();
只要原始文本有任何变化,生成的摘要结果也会发生变化。
八、Index.ets 完整代码
打开文件:
entry/src/main/ets/pages/Index.ets
完整代码如下:
import { CryptoJS } from '@ohos/crypto-js';
@Entry
@Component
struct Index {
@State courseName: string = '';
@State studentId: string = '';
@State checkDate: string = '';
@State secretCode: string = '';
@State rawText: string = '';
@State sha256Text: string = '';
@State md5Text: string = '';
@State resultText: string = '请输入打卡信息后生成摘要';
@State resultColor: string = '#999999';
aboutToAppear(): void {
this.fillSample();
this.generateDigest();
}
fillSample(): void {
this.courseName = 'OpenHarmony应用开发';
this.studentId = '20260001';
this.checkDate = '2026-05-11';
this.secretCode = 'study-hard';
this.resultText = '已填充示例数据,可以点击生成摘要进行测试';
this.resultColor = '#0A59F7';
}
clearAll(): void {
this.courseName = '';
this.studentId = '';
this.checkDate = '';
this.secretCode = '';
this.rawText = '';
this.sha256Text = '';
this.md5Text = '';
this.resultText = '请输入打卡信息后生成摘要';
this.resultColor = '#999999';
}
buildRawText(): string {
return `${this.courseName.trim()}|${this.studentId.trim()}|${this.checkDate.trim()}|${this.secretCode.trim()}`;
}
generateDigest(): void {
const course = this.courseName.trim();
const student = this.studentId.trim();
const date = this.checkDate.trim();
const secret = this.secretCode.trim();
if (course === '') {
this.resultText = '课程名称不能为空';
this.resultColor = '#E84026';
return;
}
if (student === '') {
this.resultText = '学号不能为空';
this.resultColor = '#E84026';
return;
}
if (date === '') {
this.resultText = '打卡日期不能为空';
this.resultColor = '#E84026';
return;
}
if (secret === '') {
this.resultText = '自定义口令不能为空';
this.resultColor = '#E84026';
return;
}
try {
const text = this.buildRawText();
this.rawText = text;
this.sha256Text = CryptoJS.SHA256(text).toString();
this.md5Text = CryptoJS.MD5(text).toString();
this.resultText = '摘要生成成功';
this.resultColor = '#00A870';
} catch (error) {
this.resultText = '摘要生成失败,请检查输入内容';
this.resultColor = '#E84026';
}
}
build() {
Scroll() {
Column() {
Column() {
Text('打卡摘要生成器')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor('#182431')
Text('基于 crypto-js 的学习打卡口令摘要页面')
.fontSize(14)
.fontColor('#666666')
.margin({ top: 8 })
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding({
left: 16,
right: 16,
top: 28,
bottom: 12
})
Column() {
Text('打卡信息')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#182431')
.margin({ bottom: 12 })
TextInput({
placeholder: '请输入课程名称',
text: this.courseName
})
.height(46)
.fontSize(15)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.padding({
left: 14,
right: 14
})
.onChange((value: string) => {
this.courseName = value;
})
TextInput({
placeholder: '请输入学号',
text: this.studentId
})
.height(46)
.fontSize(15)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.padding({
left: 14,
right: 14
})
.margin({ top: 12 })
.onChange((value: string) => {
this.studentId = value;
})
TextInput({
placeholder: '请输入打卡日期,例如 2026-05-11',
text: this.checkDate
})
.height(46)
.fontSize(15)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.padding({
left: 14,
right: 14
})
.margin({ top: 12 })
.onChange((value: string) => {
this.checkDate = value;
})
TextInput({
placeholder: '请输入自定义口令',
text: this.secretCode
})
.height(46)
.fontSize(15)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.padding({
left: 14,
right: 14
})
.margin({ top: 12 })
.onChange((value: string) => {
this.secretCode = value;
})
Row() {
Button('生成摘要')
.fontSize(15)
.height(42)
.layoutWeight(1)
.onClick(() => {
this.generateDigest();
})
Button('填充示例')
.fontSize(15)
.height(42)
.layoutWeight(1)
.margin({ left: 10 })
.onClick(() => {
this.fillSample();
this.generateDigest();
})
Button('清空')
.fontSize(15)
.height(42)
.layoutWeight(1)
.margin({ left: 10 })
.onClick(() => {
this.clearAll();
})
}
.width('100%')
.margin({ top: 16 })
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding(16)
.margin({
left: 16,
right: 16
})
.backgroundColor('#F7F8FA')
.borderRadius(18)
Column() {
Text('原始拼接文本')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#182431')
.margin({ bottom: 12 })
if (this.rawText === '') {
Text('生成摘要后,这里会显示参与计算的原始文本。')
.fontSize(15)
.fontColor('#999999')
.lineHeight(24)
} else {
Text(this.rawText)
.fontSize(14)
.fontColor('#333333')
.lineHeight(24)
}
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding(16)
.margin({
left: 16,
right: 16,
top: 16
})
.backgroundColor('#F7F8FA')
.borderRadius(18)
Column() {
Text('SHA-256 摘要结果')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#182431')
.margin({ bottom: 12 })
if (this.sha256Text === '') {
Text('SHA-256 摘要会显示在这里')
.fontSize(15)
.fontColor('#999999')
.lineHeight(24)
} else {
Text(this.sha256Text)
.fontSize(13)
.fontColor('#0A59F7')
.lineHeight(22)
}
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding(16)
.margin({
left: 16,
right: 16,
top: 16
})
.backgroundColor('#F7F8FA')
.borderRadius(18)
Column() {
Text('MD5 摘要结果')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#182431')
.margin({ bottom: 12 })
if (this.md5Text === '') {
Text('MD5 摘要会显示在这里')
.fontSize(15)
.fontColor('#999999')
.lineHeight(24)
} else {
Text(this.md5Text)
.fontSize(13)
.fontColor('#E84026')
.lineHeight(22)
}
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding(16)
.margin({
left: 16,
right: 16,
top: 16
})
.backgroundColor('#F7F8FA')
.borderRadius(18)
Column() {
Text('操作结果')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#182431')
.margin({ bottom: 12 })
Text(this.resultText)
.fontSize(15)
.fontColor(this.resultColor)
.lineHeight(24)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding(16)
.margin({
left: 16,
right: 16,
top: 16
})
.backgroundColor('#F7F8FA')
.borderRadius(18)
Column() {
Text('说明')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#182431')
.margin({ bottom: 12 })
Text('SHA-256 和 MD5 都属于摘要算法。摘要算法可以根据输入内容生成固定格式的结果,但不能直接反向还原原文。')
.fontSize(14)
.fontColor('#666666')
.lineHeight(24)
Text('如果任意输入内容发生变化,生成的摘要结果也会发生变化,因此可以用于简单的数据完整性校验演示。')
.fontSize(14)
.fontColor('#666666')
.lineHeight(24)
.margin({ top: 6 })
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.padding(16)
.margin({
left: 16,
right: 16,
top: 16,
bottom: 24
})
.backgroundColor('#F7F8FA')
.borderRadius(18)
}
.width('100%')
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
九、代码实现说明
1. 引入 crypto-js
页面顶部引入三方库:
import { CryptoJS } from '@ohos/crypto-js';
引入后,就可以使用 CryptoJS 提供的摘要算法方法。
本项目主要使用:
CryptoJS.SHA256()
CryptoJS.MD5()
2. 拼接原始文本
生成摘要前,先将课程名称、学号、打卡日期和自定义口令拼接成一段完整文本:
buildRawText(): string {
return `${this.courseName.trim()}|${this.studentId.trim()}|${this.checkDate.trim()}|${this.secretCode.trim()}`;
}
这里使用 | 作为分隔符,方便看清楚每个字段的边界。
例如:
OpenHarmony应用开发|20260001|2026-05-11|study-hard
这段内容就是最终参与摘要计算的原始文本。
3. 生成 SHA-256 摘要
SHA-256 摘要生成代码如下:
this.sha256Text = CryptoJS.SHA256(text).toString();
SHA-256 生成的结果长度较长,更适合用来做数据完整性校验或签名演示。
4. 生成 MD5 摘要
MD5 摘要生成代码如下:
this.md5Text = CryptoJS.MD5(text).toString();
MD5 的结果较短,常见于一些旧系统或简单校验场景。
不过需要注意,MD5 已经不适合用于真正安全要求较高的密码存储场景。本项目使用 MD5 主要是为了演示摘要生成效果,不是让你把它当安全锁。把老锁装银行金库上,多少有点对犯罪分子太友好。
5. 输入校验
生成摘要前,页面会判断每个输入框是否为空:
if (course === '') {
this.resultText = '课程名称不能为空';
this.resultColor = '#E84026';
return;
}
这样可以避免空内容参与摘要生成。
如果课程名称、学号、日期或口令为空,页面会给出对应提示。
6. 填充示例和清空功能
为了方便测试,页面提供了“填充示例”和“清空”按钮。
填充示例:
fillSample(): void {
this.courseName = 'OpenHarmony应用开发';
this.studentId = '20260001';
this.checkDate = '2026-05-11';
this.secretCode = 'study-hard';
}
清空内容:
clearAll(): void {
this.courseName = '';
this.studentId = '';
this.checkDate = '';
this.secretCode = '';
}
这样测试时不需要反复手动输入内容,毕竟重复打字这种事,实在不像文明社会该有的生产力。
十、运行效果说明
完成代码后,点击 DevEco Studio 中的运行按钮,将应用运行到 OpenHarmony 模拟器中。
运行成功后,页面顶部显示:
打卡摘要生成器
页面会自动填充一组示例数据,并生成对应的 SHA-256 和 MD5 摘要结果。
修改任意输入内容后,再次点击“生成摘要”,可以看到摘要结果发生变化。
点击“清空”按钮后,页面会清除所有输入内容和摘要结果。
十一、开发中遇到的问题
1. 找不到 @ohos/crypto-js 模块
如果代码中出现找不到模块的问题,可以先检查是否已经执行安装命令:
ohpm install @ohos/crypto-js
同时检查项目中是否存在:
oh_modules
oh-package-lock.json5
如果依赖没有正确安装,可以重新执行安装命令。
2. import 导入报错
如果下面代码导入时报错:
import { CryptoJS } from '@ohos/crypto-js';
可以尝试使用另一种导入方式:
import CryptoJS from '@ohos/crypto-js';
如果仍然报错,可以先确认 oh-package.json5 中是否已经正确写入依赖,并尝试重新同步项目或重启 DevEco Studio。
DevEco Studio 偶尔需要重启才肯承认依赖存在,像极了某些人类早上需要咖啡才能承认世界存在。
3. 摘要结果每次不一样
如果输入内容完全一样,摘要结果应该保持一致。
如果每次结果不一样,需要检查:
- 课程名称是否有空格;
- 学号是否输入一致;
- 日期是否一致;
- 自定义口令是否一致;
- 拼接格式是否变化。
本项目中使用了 trim() 去掉前后空格,可以减少因为多输入空格导致摘要变化的问题。
4. 摘要算法是不是加密算法
不是。
摘要算法是单向处理,一般不能从摘要结果还原原始文本。它适合用于校验内容是否一致,而不是用于保存可以解密的内容。
如果需要真正的加密和解密,应该使用 AES、DES 等对称加密算法,并合理管理密钥。
5. SHA-256 和 MD5 有什么区别
简单来说:
| 算法 | 特点 |
|---|---|
| MD5 | 结果短,速度快,但安全性较弱 |
| SHA-256 | 结果更长,安全性更强,更适合现代场景 |
本项目同时展示两个结果,主要是为了让开发者更直观地看到不同摘要算法生成结果的差异。
十二、总结
本篇完成了一个基于 @ohos/crypto-js 的学习打卡口令摘要生成器。项目通过用户输入课程名称、学号、打卡日期和自定义口令,拼接成原始文本,再使用 SHA-256 和 MD5 生成摘要结果,并通过 ArkUI 展示在页面中。
通过本次实践,我主要完成了以下内容:
- 安装并使用
@ohos/crypto-js三方库; - 在 ArkTS 页面中引入
CryptoJS; - 使用
TextInput接收打卡信息; - 拼接原始摘要文本;
- 使用
CryptoJS.SHA256()生成 SHA-256 摘要; - 使用
CryptoJS.MD5()生成 MD5 摘要; - 使用 ArkUI 构建卡片式工具页面;
- 实现填充示例、清空内容和状态提示;
- 在模拟器中完成运行验证。
虽然这个项目只是一个基础摘要生成页面,但它已经包含了工具类应用中常见的输入、校验、处理、结果展示和异常提示流程。
后续可以继续扩展为一个更完整的安全工具页面,例如:
- 添加 HMAC-SHA256 签名;
- 添加 AES 加密解密;
- 添加摘要结果复制功能;
- 添加随机盐值生成;
- 添加历史记录保存;
- 添加接口签名模拟;
- 添加文件摘要计算;
- 添加打卡二维码生成。
整体来看,@ohos/crypto-js 可以帮助开发者更方便地在 OpenHarmony 项目中实现摘要、加密等相关功能。通过这个项目,可以更清楚地理解 OpenHarmony 中三方库接入、摘要算法调用和 ArkUI 页面展示之间的关系。
更多推荐
所有评论(0)