mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 00:55:09 -07:00
[DeckList] Extract deck-hash encoding helpers (#7321)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
c45cb8ac32
commit
dce9efcaa3
1 changed files with 43 additions and 16 deletions
|
|
@ -7,6 +7,47 @@
|
|||
|
||||
static constexpr int MAX_DECK_SIZE = 1e5;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Expands card nodes into one lowercase name entry per copy.
|
||||
*
|
||||
* @param nodes The card nodes to expand.
|
||||
* @param prefix Optional prefix prepended to every entry (e.g. "SB:" for the sideboard).
|
||||
* @return One entry per copy, in node order.
|
||||
*/
|
||||
QStringList cardNodesToCopies(const QList<const DecklistCardNode *> &nodes, const QString &prefix = {})
|
||||
{
|
||||
QStringList result;
|
||||
for (auto node : nodes) {
|
||||
for (int i = 0; i < node->getNumber(); ++i) {
|
||||
result.append(prefix + node->getName().toLower());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Packs the first five bytes of a SHA-1 digest into a compact base-32 number.
|
||||
*
|
||||
* The bytes are placed in most-significant-byte-first order (byte 0 shifted by 32,
|
||||
* byte 4 unshifted) so decks that only differ in their low-order hash bytes still
|
||||
* produce distinct identifiers.
|
||||
*
|
||||
* @return The 8-character base-32 representation of the packed number.
|
||||
*/
|
||||
QString encodeDeckHash(const QByteArray &digest)
|
||||
{
|
||||
quint64 number = 0;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
number |= static_cast<quint64>(static_cast<unsigned char>(digest[i])) << (32 - 8 * i);
|
||||
}
|
||||
return QString::number(number, 32).rightJustified(8, '0');
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
DecklistNodeTree::DecklistNodeTree() : root(new InnerDecklistNode())
|
||||
{
|
||||
}
|
||||
|
|
@ -83,25 +124,11 @@ QString DecklistNodeTree::computeDeckHash() const
|
|||
auto mainDeckNodes = getCardNodes({DECK_ZONE_MAIN});
|
||||
auto sideDeckNodes = getCardNodes({DECK_ZONE_SIDE});
|
||||
|
||||
static auto nodesToCardList = [](const QList<const DecklistCardNode *> &nodes, const QString &prefix = {}) {
|
||||
QStringList result;
|
||||
for (auto node : nodes) {
|
||||
for (int i = 0; i < node->getNumber(); ++i) {
|
||||
result.append(prefix + node->getName().toLower());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
QStringList cardList = nodesToCardList(mainDeckNodes) + nodesToCardList(sideDeckNodes, "SB:");
|
||||
QStringList cardList = cardNodesToCopies(mainDeckNodes) + cardNodesToCopies(sideDeckNodes, "SB:");
|
||||
|
||||
cardList.sort();
|
||||
QByteArray deckHashArray = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1);
|
||||
quint64 number = (((quint64)(unsigned char)deckHashArray[0]) << 32) +
|
||||
(((quint64)(unsigned char)deckHashArray[1]) << 24) +
|
||||
(((quint64)(unsigned char)deckHashArray[2] << 16)) +
|
||||
(((quint64)(unsigned char)deckHashArray[3]) << 8) + (quint64)(unsigned char)deckHashArray[4];
|
||||
return QString::number(number, 32).rightJustified(8, '0');
|
||||
return encodeDeckHash(deckHashArray);
|
||||
}
|
||||
|
||||
void DecklistNodeTree::write(QXmlStreamWriter *xml) const
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue