QString转QByteArray数据丢失-特殊字符

 一、可能原因

1、编码格式差异:QString和QByteArray有本质区别。QString是一个Unicode字符串,其受编码格式影响,而QByteArray是一个字节序列。在进行QSting转QByteArray的过程中,最常见的方式是将Unicode字符串转换为UTF-8编码的字节序列。

2、包含空字符:QString 编码结束符为空字符(16进制00,\X00),因此在特殊情况下比如异或加密后会出现空字符,如果通过异或解密便会丢失数据。

二、解决办法

1、编码格式问题可以在转换前指定编码格式,一个采用UTF-8,如下:

    QTextCodec *codec=QTextCodec::codecForName("UTF-8");
    QByteArray qbtBuffer = codec->fromUnicode(qsData);

2、空字符或特殊字符,在异或加密前转换成QChar或QByteArray,加密数据采用QByteArray存储,解密时对QByteArray格式进行存储。

//测试代码1
 QString qsText("Beijing XXXX Technology Co., Ltd");
 QString qsEncryption=this->getXOREncryption(qsText,111);
 QString qsDecryption=this->getXOREncryption(qsEncryption,111);
 qDebug()<<"qsEncryption=="<<qsEncryption;
 qDebug()<<"qsDecryption=="<<qsDecryption;

//输出结果
qsEncryption== "-\n\u0006\u0005\u0006\u0001\bO7777O;\n\f\u0007\u0001"
qsDecryption== "Beijing XXXX Techn"


QString getXOREncryption(const QString &qsData, char cKey)
{
    //采用异或加密
    QTextCodec *codec=QTextCodec::codecForName("UTF-8");
    QByteArray qbtBuffer = codec->fromUnicode(qsData);
    int iSize = qbtBuffer.size();
    for (int i = 0; i < iSize; i++) {
        qbtBuffer[i] = qbtBuffer.at(i) ^ cKey;
    }
    return QLatin1String(qbtBuffer);
}

以上明显可以看出,解密后数据丢失,原因是疑惑加密后字符'O'为空字符,从而导致存储与解密的丢失。

//测试代码2

QString qsText("Beijing XXXX Technology Co., Ltd");
QByteArray bytData=qsText.toLatin1();
QByteArray bytEncryption=this->getXOREncryption(bytData,111);
QByteArray bytDecryption=this->getXOREncryption(bytEncryption,111);
qDebug()<<"bytEncryption=="<<bytEncryption;
qDebug()<<"bytDecryption=="<<bytDecryption;

//输出结果
bytEncryption== "-\n\x06\x05\x06\x01\bO7777O;\n\f\x07\x01\x00\x03\x00\b\x16O,\x00""ACO#\x1B\x0B"
bytDecryption== "Beijing XXXX Technology Co., Ltd"


QByteArray LisenceKey::getXOREncryption(const QByteArray &bytData, char cKey)
{
    QByteArray qbtBuffer=bytData;
    int iSize = qbtBuffer.size();
    for (int i = 0; i < iSize; i++) {
        qbtBuffer[i] = qbtBuffer.at(i) ^ cKey;
    }
    return qbtBuffer;
}

以上可以看出,通过QByteArray存储保留了完整信息。

三、应用

1、将数据加密后存储:注意,由于有特殊格式尤其是空字符,不要采用数据流的方式。

//加密写入文件	
QString qsFilePath = qsPath;
if (qsFilePath.isEmpty()) qsFilePath = QString("./lisence.lic");
QFile file(qsFilePath);
if (file.open(QFile::WriteOnly | QIODevice::Text)) {
	//QTextStream out(&file);
	//out << this->getXOREncryption(lstData.join("|"));
	file.write(getXOREncryption(lstData.join("|").toLatin1())); 
	file.close();
}


//读取数据并解密
QFile keyFile(this->m_qsLisencePath);
if (keyFile.exists() && keyFile.size() > 0 && keyFile.open(QFile::ReadOnly | QIODevice::Text)) {
	QString keyData = QString(this->getXOREncryption(keyFile.readAll()));
	lstData = keyData.split("|", Qt::KeepEmptyParts);
}
return lstData;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值