前言
实习期间大部分时间都是在和各种 bug 打交道,这个也算是为数不多的开发任务了。明天华子面试,今晚过一遍。
HBC注册模块(HBCRegister)
在 HBCRegister.txt
文件中,HBCRegister
类主要实现了一个软件注册对话框,允许用户输入注册码并进行验证。这个模块的核心功能是管理软件的授权注册,包括读取用户输入的注册码、验证该注册码是否合法,以及处理许可证文件。这是一个典型的注册流程,广泛应用于商业软件的许可管理中。
以下是对该模块各部分的详细分析:
1. 类定义与构造函数
1 | class HBCRegister : public BaseDialog |
构造函数
HBCRegister(QWidget *parent)
:- 初始化界面控件,使用
setupUi
函数加载用户界面。 - 为“取消”和“注册”按钮设定信号与槽的连接。用户点击按钮后,触发相应的槽函数
clickOnCancel()
或clickOnRegist()
。 - 使用
generateSoftWareId()
生成软件的序列号。 - 利用
QTimer::singleShot
延迟设置窗口的高度值(因为直接获取可能会因界面尚未完全初始化而出错)。
- 初始化界面控件,使用
析构函数
~HBCRegister()
:- 销毁
HBCRegister
对象时清理内存。
- 销毁
2. 界面初始化与语言切换
initRegisterInfo()
:- 该函数负责初始化注册信息,比如从
utils::HardwareInfo
中读取软件的序列号(tryReadSerialNumber()
)并在界面上显示出来。
- 该函数负责初始化注册信息,比如从
switchToEnglishUI()
:- 这是一个切换为英文界面的功能,用于国际化。当软件运行在英文模式下时,该函数修改界面上的控件文本(如按钮、标签等)的显示内容,并设置英文版的图标和窗口标题。
3. 生成软件ID
1 | void HBCRegister::generateSoftWareId() |
- 该函数从硬件信息模块中读取软件的序列号,用于后续的注册验证。通过
utils::HardwareInfo::tryReadSerialNumber
函数获取序列号,并将其显示在界面的指定标签(labSerialNumBer
)中。 - 这里的软件ID与点云处理软件模块(
LidarPostProcess
)相关,表明该系统可能应用于处理LiDAR(激光雷达)数据的软件。
4. 取消与注册功能
clickOnCancel()
:- 当用户点击“取消”按钮时,调用该函数,关闭注册窗口,不进行任何操作。
1
2
3
4void HBCRegister::clickOnCancel()
{
this->reject();
}
- 当用户点击“取消”按钮时,调用该函数,关闭注册窗口,不进行任何操作。
clickOnRegist()
:- 这是用户点击“注册”按钮时触发的核心逻辑。首先,从输入框读取用户输入的注册码,打开对应的文件,并进行注册验证。
- 验证过程调用了
LicenseReader
类,该类读取许可证文件并进行解析。如果许可证无效或文件为空,弹出提示框提示用户相关信息。 - 验证过程中使用了
hbc::ZHDAuthority
类来设置许可证并验证授权信息。通过验证后,软件授权将被激活,注册成功;否则,提示注册失败。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47void HBCRegister::clickOnRegist()
{
auto licesefile = ui->edtRegisterCode->text();
QFile file(licesefile);
if (!file.open(QIODevice::ReadOnly)){
QMessageBox::warning(this, "HBC", tr("Failed to read license:%1!").arg(licesefile));
return;
}
auto content = file.readAll();
if (content.isEmpty()){
QMessageBox::warning(this, "HBC", tr("License:%1 is empty!").arg(licesefile));
return;
}
hbc::LicenseReader reader;
if (!reader.read(content))
{
QMessageBox::warning(this, "HBC", tr("License:%1 is invaild!").arg(licesefile));
return;
}
hbc::IAuthority::LisenceState state = hbc::IAuthority::NoLisence;
ProcessDialog::Process(this, [&](ProcessDialog* processDlg) {
processDlg->setValue(0);
processDlg->setRange(0, content.size());
QString subSys("zhd");
hbc::ZHDAuthority authority(subSys, 0, true);
auto license = reader.getDefaultLicense();
authority.setLicense(license);
authority.valid();
state = authority.getState();
});
if (state == hbc::IAuthority::Vaild)
{
QMessageBox::information(this, QString(), tr("Register success!"));
this->accept();
}
else
{
QMessageBox::information(this, QString(), tr("Register failed!"));
}
}
5. 扫描许可证文件
clickOnScanLicense()
:- 该函数为用户提供了一个文件选择器,允许用户从文件系统中选择一个许可证文件,然后将其路径显示在界面的输入框中。
1
2
3
4
5
6
7
8
9void HBCRegister::clickOnScanLicense()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select a license file"), QString(),
tr("License File") + "(*.reg);;" + tr("All File")+"(*.*)");
if (!fileName.isEmpty())
{
ui->edtRegisterCode->setText(fileName);
}
}
- 该函数为用户提供了一个文件选择器,允许用户从文件系统中选择一个许可证文件,然后将其路径显示在界面的输入框中。
6. 关键类的应用
**
hbc::LicenseReader
**:LicenseReader
类用于读取和解析许可证文件。通过调用reader.read(content)
,可以解析文件中的授权信息,并通过getDefaultLicense()
获取默认的许可证数据。这个步骤对验证许可证的合法性至关重要。
**
hbc::ZHDAuthority
**:ZHDAuthority
类是核心的许可证验证类,负责管理注册模块信息的验证。它可以读取并解密授权码,并判断授权状态(如授权是否有效或过期)。- 在
clickOnRegist()
函数中,通过调用authority.valid()
来检查授权码是否合法,并获取授权状态。如果授权状态为IAuthority::Vaild
,则注册成功。
总结:
HBCRegister.txt
文件实现了软件注册的完整流程,涉及以下几个关键步骤:
- 读取用户输入的注册码或许可证文件。
- 验证许可证文件的合法性,解析其内容。
- 使用授权管理模块(如
ZHDAuthority
)进行许可证的解密和验证。 - 根据授权结果,通知用户注册成功或失败。
这个模块为软件的商业授权提供了保障,确保只有合法用户才能使用相关的软件功能。
许可证管理模块(iauthority、LicenseReader、ZHDAuthority、SoftdogAuthority)
许可证管理模块是你项目中的核心部分,负责处理软件授权和验证,确保用户合法使用软件。这个模块涉及多个文件,包括 iauthority
、LicenseReader
、ZHDAuthority
和 SoftdogAuthority
。这些文件共同实现了对软件许可证的读取、验证、管理和过期检查等功能,涵盖了软硬件的授权机制(如软件加密狗和注册码)。
下面我会详细分析每个文件的功能和其在许可证管理中的作用。
1. 授权接口与基础管理(iauthority
)
iauthority
定义了一个接口类 IAuthority
,是授权管理的基础框架。所有具体的授权机制(如软件授权、硬件加密狗)都会基于这个接口实现。
核心代码分析:
1 | class IAuthority |
主要功能:
LisenceState
(授权状态):定义了授权的几种可能状态,包括无授权、非法授权、过期授权和合法授权。- 虚函数(Virtual Functions):
setLicense
、getLicense
、valid
等函数为虚函数,具体授权类(如ZHDAuthority
和SoftdogAuthority
)会实现这些接口,提供不同的授权管理方式。 - 子授权管理:该类支持子系统授权,即一个授权可能包含多个子授权,通过
getSubAuthorityList
方法可以获取所有子授权。
这个类作为一个基础接口,定义了整个授权系统的规范,任何具体的授权类都需要继承并实现这些功能。
2. 许可证文件读取与解析(LicenseReader
)
LicenseReader
中定义了 LicenseReader
类,它负责读取和解析存储在文件中的许可证信息。这个类通常用于软件注册时,从文件中提取授权数据。
核心代码分析:
1 | class LicenseReader |
主要功能:
- 读取许可证文件:
read(QIODevice& device)
函数从文件中读取许可证数据,并将其解析为 JSON 格式存储在m_licenseMap
中。 - 获取许可证:
getLicense
和getDefaultLicense
提供了获取具体系统的许可证和默认许可证的功能,通常用于不同模块或子系统的授权管理。 - 多系统支持:
m_licenseMap
是一个哈希表,可以支持多个子系统(如LiDAR
、GNSS
等)分别管理其对应的授权信息。
使用场景:
- 当用户上传许可证文件时,该类读取文件并解析其中的授权信息,为后续的授权验证提供数据支持。
3. 软件授权验证(ZHDAuthority
)
ZHDAuthority
文件实现了具体的授权管理类 ZHDAuthority
,它基于 IAuthority
接口,负责处理软件注册码的解密和验证。
核心代码分析:
1 | class ZHDAuthority : public QObject, public IAuthority |
主要功能:
- 授权码验证:
valid()
函数负责验证授权码是否合法。它通过解密授权码(DecryptCode
)来确认其有效性,并根据结果返回不同的授权状态。 - 过期时间管理:通过
getTimeOut()
函数获取许可证的过期时间,并在授权时检查该时间,确保授权没有过期。 - 授权状态计算:
computeState()
函数根据授权码的解密结果、当前时间和授权模块的状态计算最终的授权状态(如过期、无授权等)。 - 试用期管理:
getTrialTime()
函数负责管理试用期授权,未注册用户可以享有一个月的试用期。
使用场景:
- 该类适用于处理具体的软件模块授权,如 LiDAR 数据处理软件等。通过解密授权码,可以确定用户是否拥有合法的使用权,并进行授权激活或提示用户注册。
4. 硬件加密狗授权验证(SoftdogAuthority.txt
)
SoftdogAuthority
实现了 SoftdogAuthority
类,用于处理硬件加密狗(即硬件授权)验证。
核心代码分析:
1 | class SoftdogAuthority : public QObject |
主要功能:
- 硬件加密狗验证:
valid()
函数通过调用DecryptSoftdog
解密加密狗中的信息,检查硬件加密狗的合法性(如是否过期,是否为当前软件模块授权)。 - 许可证状态管理:该类通过
getState()
和computeState()
管理授权状态,并根据硬件加密狗的信息返回当前授权是否合法。 - 授权到期时间:通过读取加密狗中存储的信息,获取授权的到期时间(
getTimeOut()
)。
使用场景:
- 该类专门用于验证硬件加密狗授权。当软件依赖于硬件加密狗进行保护时,这个类会检查加密狗是否插入,授权是否有效,并防止未授权的用户使用软件。
总结
1. **iauthority
**:
- 提供了授权系统的基础接口,定义了授权验证的标准流程(如验证授权码、检查过期时间等)。
2. **LicenseReader
**:
- 负责读取和解析许可证文件,确保软件能够正确提取用户上传的授权数据。
3. **ZHDAuthority
**:
- 实现了具体的软件授权验证逻辑,通过解密软件授权码来管理软件模块(如 LiDAR)的使用权。它还能管理授权过期时间、试用期等。
4. **SoftdogAuthority
**:
- 专门处理硬件加密狗授权,通过解密硬件授权信息确保加密狗的有效性。它支持硬件层面的保护,通常用于更严格的版权保护方案。
通过这些模块,整个软件授权系统具备了较为全面的功能,能够有效管理不同形式(硬件和软件)的授权,确保软件的合法使用。
面试
在面试中,面试官可能会根据你在实习期间的工作经历询问以下内容。以下是一些可能的问题及回答建议:
1. 你在实习期间的主要工作职责是什么?
- 回答要点:
- 我主要负责软件的注册和授权系统的开发。包括处理软件许可证的验证,硬件加密狗授权管理,读取硬件信息,并结合软件、硬件的授权保护机制,确保软件模块的合法使用。
- 我编写了代码来处理从用户输入到注册码验证的整个流程,具体涉及许可证文件的解析、授权状态的管理、授权过期的检测等。
2. 请描述你实现的授权系统是如何工作的?
- 回答要点:
- 我们的授权系统分为两部分:硬件加密狗(Softdog)和软件注册码(如 ZHDAuthority)。
- 软件注册码系统通过解密授权码来验证用户是否有合法的使用权限,并检查授权是否已过期。我们还支持试用期功能,允许用户在购买前试用软件。
- 硬件加密狗则通过插入物理设备(加密狗),软件会读取其中的授权信息并验证加密狗的有效性,如果没有加密狗,软件将无法运行。
3. 你如何确保授权系统的安全性和可靠性?
- 回答要点:
- 为了确保授权系统的安全性,我们使用了加密和解密技术来保护授权码信息。用户的授权码在存储和传输过程中是加密的,解密操作只在本地进行。
- 硬件加密狗通过物理设备增强了安全性,只有拥有加密狗的用户才能访问特定的软件功能,避免了软件的非法复制和使用。
- 我们还设计了定期检查授权状态的机制,确保授权信息不会过期或被篡改。
4. 你如何处理许可证的读取和解析?
- 回答要点:
- 我们使用了
LicenseReader
类来处理许可证文件的读取,许可证文件通常以 JSON 格式存储,包含多个系统或模块的授权信息。 - 通过解析这些文件,我们可以获取用户的授权信息,并根据具体的授权模块来决定软件的使用权限。整个过程支持多个子系统的授权管理,比如 GNSS、RTK、LiDAR 等模块。
- 我们使用了
5. 你们如何管理软件模块的授权?
- 回答要点:
- 每个软件模块都有单独的授权控制,比如点云处理模块、扫描仪标定模块等。我们通过
ZHDAuthority
类来管理这些模块的授权。 - 授权系统根据用户的授权码解密出各个模块的注册信息,只有用户的授权码中包含相应模块的注册信息时,该模块才能被启用。
- 我们还支持子授权系统,一个主授权可以包含多个子模块的授权,这在复杂的软件系统中非常实用。
- 每个软件模块都有单独的授权控制,比如点云处理模块、扫描仪标定模块等。我们通过
6. 你在开发过程中遇到了哪些挑战?你是如何解决的?
- 回答要点:
- 一个主要的挑战是确保软件和硬件授权系统的整合。我们需要确保不同形式的授权(如软件注册码和硬件加密狗)能够无缝协作,提供一致的用户体验。
- 另一个挑战是处理网络连接不稳定时的授权验证。我们设计了离线模式下的授权检查,并在网络恢复时同步更新授权状态。
- 我们还要确保授权系统的灵活性和扩展性,特别是在未来添加新的模块或功能时,系统能够轻松适配。
7. 你使用了哪些技术和工具来开发这个授权系统?
- 回答要点:
- 开发过程中我们使用了 C++ 结合 Qt 框架来实现用户界面和底层逻辑交互。
- 使用了 Windows 管理工具(WMIC)来获取硬件信息,如 CPU ID、BIOS 序列号等。
- 我们还使用了 JSON 解析库来处理许可证文件,确保其结构化存储和读取。
- 硬件加密狗的处理通过特定的加密和解密算法来保证安全性,并使用了插入设备后的即时检测机制。
8. 你如何验证和测试你开发的授权系统?
- 回答要点:
- 我们通过多种场景测试授权系统,包括合法授权、无效授权、过期授权、硬件加密狗插入和移除等情况,确保系统在不同场景下都能正确响应。
- 还进行了网络断开与恢复的测试,确保在离线情况下也能进行授权检测,并在恢复连接时更新授权状态。
- 测试包括模拟用户输入错误的注册码、使用过期许可证、以及尝试篡改授权文件等,以确保系统的安全性和鲁棒性。
总结:
面试中,面试官可能会围绕你的实习经历从技术、挑战、实现细节、以及安全性等方面发问。你的回答应尽量涵盖以下几个要点:
- 系统的总体架构(软件与硬件授权相结合)。
- 你负责实现的模块及其核心功能。
- 授权系统的安全性、灵活性和可靠性。
- 遇到的技术挑战和解决方案。
通过清晰表达你的工作思路和技术决策,能够展示出你在实习期间的贡献与技术能力。
在实习期间,我参与了一个授权管理系统的开发项目。该系统主要负责处理软件的授权验证和管理,支持软狗授权和中海达授权。项目包含多个模块:授权接口IAuthority
定义了核心授权逻辑,LicenseReader
负责读取和解析许可证文件,SoftdogAuthority
和ZHDAuthority
分别实现了软狗和中海达的授权验证。用户通过注册界面HBCRegister
输入许可证文件,系统进行解密和验证,确保授权的合法性和有效性。项目的核心任务是实现授权验证、状态管理和试用期控制。
根据你提供的文件和前面的项目逻辑分析,我将结合具体代码片段进行详细解释,以帮助你更好地理解各模块的具体实现及其在项目中的作用。
1. IAuthority 类【8†source】
这是项目中授权管理的核心接口类,定义了授权验证的基础框架,允许不同授权实现类继承并实现其功能。
1 | class IAuthority |
解释:
LisenceState
枚举:定义了四种授权状态:InVaild
(非法)、Vaild
(合法)、OutOfDate
(过期)和NoLisence
(无授权)。- 虚函数:
setLicense
、getLicense
、valid
等是虚函数,由具体的授权类(如SoftdogAuthority
或ZHDAuthority
)进行实现。虚函数机制使得子类可以根据具体授权机制实现不同的授权验证逻辑。 - 子授权:
getSubAuthorityList
函数允许扩展授权为树形结构,方便处理多层次的授权。
2. LicenseReader 类【9†source】
该类负责读取授权文件,并将其内容解析为二进制授权数据。
1 | class LicenseReader |
解释:
read
函数:负责从设备或者QByteArray
中读取授权文件,解析成JSON格式,然后转换为QByteArray
类型的数据,存储在m_licenseMap
中。getLicense
函数:根据系统名称从m_licenseMap
中获取对应的授权信息。如果名称不匹配,返回空的QByteArray
。- **
getDefaultLicense
**:默认获取名为“zhd”的系统授权信息,用于中海达产品的默认授权处理。
1 | bool LicenseReader::read(const QByteArray& data) |
解释:
- 该段代码读取授权文件内容并解析成JSON对象。每个系统的授权信息都存储为字符串,转化为二进制数据后放入
m_licenseMap
哈希表中。
3. SoftdogAuthority 类【10†source】
这是软狗(硬件加密狗)授权的实现类,继承了IAuthority
,实现具体的软狗授权逻辑。
1 | class SoftdogAuthority :public QObject |
解释:
- 授权验证:
valid
函数调用computeState
来验证授权码是否合法。computeState
从授权码中解密信息,检查授权状态。 - 授权数据设置与获取:通过
setLicense
和getLicense
来设置和获取授权码。 - 时间管理:
getNewestTime
函数返回最新的时间信息(可以是本地时间或网络时间),确保授权验证依赖最新的时间。
1 | bool SoftdogAuthority::valid() |
解释:
- 授权状态变化:当授权状态改变时,
stateChange
信号会发出,用于通知其他模块(如UI界面)更新授权状态。
1 | SoftdogAuthority::CodeInfo SoftdogAuthority::DecryptSoftdog(QByteArray code) |
解释:
- 授权码解密:
DecryptSoftdog
函数将授权码解析成JSON对象,并提取出重要信息(如regTime
注册时间、授权码的合法性)。这些信息用于后续的授权验证。
4. ZHDAuthority 类【11†source】
这是中海达授权的具体实现,继承了IAuthority
,并且与软狗授权有类似的功能。
1 | class ZHDAuthority : public QObject, public IAuthority |
解释:
- 授权状态:
ZHDAuthority
管理中海达产品的授权,valid
函数验证授权码并检查是否已过期,getState
获取当前授权状态。 - 位域处理:每个模块的授权状态通过位域
RegisterModuel::BitInfo
管理,某个位为1表示该模块已授权。
1 | LisenceState ZHDAuthority::computeState() |
解释:
- 授权状态计算:
computeState
遍历所有授权码,调用getCodeState
逐一验证授权码是否合法。如果找到一个合法授权码,状态设为Vaild
。
5. HBCRegister 类(注册界面)【12†source】
这是用户交互界面,用于处理许可证输入和授权验证。
1 | class HBCRegister : public BaseDialog |
1 | void HBCRegister::click |
解释:
- 用户输入处理:当用户输入许可证文件后,
clickOnRegist
函数会读取文件内容,并使用LicenseReader
解析文件,随后调用ZHDAuthority
的valid
函数进行授权验证。 - 授权验证反馈:如果授权验证成功,界面会显示注册成功信息。
总结:
这个项目的核心是实现一个多层次、多模块的授权管理系统,通过IAuthority
接口定义统一的授权逻辑,各个子类(如SoftdogAuthority
、ZHDAuthority
)实现具体的授权验证机制。LicenseReader
负责从外部文件读取授权数据,HBCRegister
作为用户界面与用户进行交互,最终完成许可证的输入与验证。