1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00
qTox/src/core/toxid.cpp

228 lines
5.8 KiB
C++
Raw Normal View History

/*
Copyright © 2015 by The qTox Project Contributors
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
qTox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with qTox. If not, see <http://www.gnu.org/licenses/>.
*/
2015-05-18 02:17:14 +08:00
#include "toxid.h"
#include "core.h"
2015-05-18 02:17:14 +08:00
#include <tox/tox.h>
#include <qregularexpression.h>
2016-12-26 04:37:37 +08:00
// Tox doesn't publicly define these
#define NOSPAM_BYTES 4
#define CHECKSUM_BYTES 2
#define PUBLIC_KEY_HEX_CHARS (2*TOX_PUBLIC_KEY_SIZE)
#define NOSPAM_HEX_CHARS (2*NOSPAM_BYTES)
#define CHECKSUM_HEX_CHARS (2*CHECKSUM_BYTES)
#define TOXID_HEX_CHARS (2*TOX_ADDRESS_SIZE)
2015-05-18 02:17:14 +08:00
2016-07-27 06:21:22 +08:00
/**
2016-08-01 16:20:56 +08:00
* @class ToxId
* @brief This class represents a Tox ID.
*
* An ID is composed of 32 bytes long public key, 4 bytes long NoSpam
* and 2 bytes long checksum.
*
* e.g.
* @code
* | C7719C6808C14B77348004956D1D98046CE09A34370E7608150EAD74C3815D30 | C8BA3AB9 | BEB9
* | / |
* | / NoSpam | Checksum
* | Public Key (PK), 32 bytes, 64 characters / 4 bytes | 2 bytes
* | | 8 characters| 4 characters
* @endcode
*/
2016-07-27 06:21:22 +08:00
/**
2016-08-01 16:20:56 +08:00
* @brief The default constructor. Creates an empty Tox ID.
*/
2015-05-18 02:17:14 +08:00
ToxId::ToxId()
2016-12-26 04:37:37 +08:00
: toxId()
2015-05-18 02:17:14 +08:00
{}
2016-07-27 06:21:22 +08:00
/**
2016-08-01 16:20:56 +08:00
* @brief The copy constructor.
* @param other ToxId to copy
*/
2015-05-18 02:17:14 +08:00
ToxId::ToxId(const ToxId &other)
2016-12-26 04:37:37 +08:00
: toxId(other.toxId)
2015-05-18 02:17:14 +08:00
{}
2016-07-27 06:21:22 +08:00
/**
2016-12-26 04:37:37 +08:00
* @brief Create a Tox ID from a QString.
2016-08-01 16:20:56 +08:00
*
* If the given id is not a valid Tox ID, then:
* publicKey == id and noSpam == "" == checkSum.
*
* @param id Tox ID string to convert to ToxId object
2016-07-27 06:21:22 +08:00
*/
2015-05-18 02:17:14 +08:00
ToxId::ToxId(const QString &id)
{
if (isToxId(id))
{
2016-12-26 04:37:37 +08:00
toxId = QByteArray::fromHex(id.toLatin1());
}
else if(id.length() >= PUBLIC_KEY_HEX_CHARS)
{
toxId = QByteArray::fromHex(id.left(PUBLIC_KEY_HEX_CHARS).toLatin1());
2015-05-18 02:17:14 +08:00
}
else
{
2016-12-26 04:37:37 +08:00
toxId = QByteArray(TOX_ADDRESS_SIZE, 0x00); // invalid id string
}
}
/**
* @brief Create a Tox ID from a QByteArray.
*
* If the given id is not a valid Tox ID, then:
* publicKey == id and noSpam == "" == checkSum.
*
* @param id Tox ID string to convert to ToxId object
*/
ToxId::ToxId(const QByteArray &rawId)
{
if(rawId.length() == TOX_SECRET_KEY_SIZE)
{
toxId = QByteArray(rawId); // construct from PK only
}
else if (rawId.length() == TOX_ADDRESS_SIZE
&& isToxId(rawId.toHex().toUpper()))
{
toxId = QByteArray(rawId); // construct from full toxid
}
else
{
toxId = QByteArray(TOX_ADDRESS_SIZE, 0x00); // invalid id string
2015-05-18 02:17:14 +08:00
}
}
2016-07-27 06:21:22 +08:00
/**
2016-08-01 16:20:56 +08:00
* @brief Compares, that public key equals.
* @param other Tox ID to compare.
* @return True if both Tox ID have same public keys, false otherwise.
*/
2015-05-18 02:17:14 +08:00
bool ToxId::operator==(const ToxId& other) const
{
2016-12-26 04:37:37 +08:00
return getPublicKey() == other.getPublicKey();
2015-05-18 02:17:14 +08:00
}
2016-07-27 06:21:22 +08:00
/**
2016-08-01 16:20:56 +08:00
* @brief Compares, that only public key not equals.
* @param other Tox ID to compare.
* @return True if both Tox ID have different public keys, false otherwise.
*/
2015-05-18 02:17:14 +08:00
bool ToxId::operator!=(const ToxId &other) const
{
2016-12-26 04:37:37 +08:00
return getPublicKey() != other.getPublicKey();
2015-05-18 02:17:14 +08:00
}
2016-07-27 06:21:22 +08:00
/**
2016-08-01 16:20:56 +08:00
* @brief Returns Tox ID converted to QString.
* @return The Tox ID as QString.
*/
2015-05-18 02:17:14 +08:00
QString ToxId::toString() const
{
2016-12-26 04:37:37 +08:00
return toxId.toHex().toUpper();
2015-05-18 02:17:14 +08:00
}
2016-07-27 06:21:22 +08:00
/**
2016-08-01 16:20:56 +08:00
* @brief Clears all elements of the Tox ID.
*/
2015-05-18 02:17:14 +08:00
void ToxId::clear()
{
2016-12-26 04:37:37 +08:00
toxId.clear();
2015-05-18 02:17:14 +08:00
}
2016-07-27 06:21:22 +08:00
/**
* @brief Check, that id is probably a valid Tox ID.
2016-08-01 16:20:56 +08:00
* @param id Tox ID to check.
* @return True if the string can be a ToxID, false otherwise.
* @note Doesn't validate checksum.
2016-08-01 16:20:56 +08:00
*/
bool ToxId::isValidToxId(const QString& id)
2015-05-18 02:17:14 +08:00
{
const QRegularExpression hexRegExp("^[A-Fa-f0-9]+$");
2016-12-26 04:37:37 +08:00
return id.length() == TOXID_HEX_CHARS && id.contains(hexRegExp);
}
/**
* @brief Gets the Public Key part of the ToxID
* @return Public Key of the ToxID
*/
QByteArray ToxId::getPublicKey() const
{
return toxId.mid(0, TOX_PUBLIC_KEY_SIZE);
}
/**
* @brief Returns the Public Key converted to QString.
* @return The Public Key as QString.
*/
QString ToxId::getPublicKeyString() const
{
return getPublicKey().toHex().toUpper();
}
/**
* @brief Returns the NoSpam value converted to QString.
* @return The NoSpam value as QString or "" if the ToxId was constructed from a Public Key.
*/
QString ToxId::getNoSpamString() const
{
if(toxId.length() == TOX_ADDRESS_SIZE)
{
return toxId.mid(TOX_PUBLIC_KEY_SIZE, NOSPAM_BYTES).toHex().toUpper();
}
return {};
2015-05-18 02:17:14 +08:00
}
/**
* @brief Check, that id is a valid Tox ID.
* @param id Tox ID to check.
* @return True if id is a valid Tox ID, false otherwise.
*/
bool ToxId::isToxId(const QString& id)
{
if (!isValidToxId(id))
{
return false;
}
2016-12-26 04:37:37 +08:00
uint32_t size = PUBLIC_KEY_HEX_CHARS + NOSPAM_HEX_CHARS;
QString publicKeyStr = id.left(size);
2016-12-26 04:37:37 +08:00
QString checksumStr = id.right(CHECKSUM_HEX_CHARS);
QByteArray publicKey = QByteArray::fromHex(publicKeyStr.toLatin1());
QByteArray checksum = QByteArray::fromHex(checksumStr.toLatin1());
uint8_t check[2] = {0};
for (uint32_t i = 0; i < size / 2; i++)
{
check[i % 2] ^= publicKey.data()[i];
}
QByteArray caclulated(reinterpret_cast<char*>(check), 2);
return caclulated == checksum;
}