#include #include #include namespace Xmpp { const std::string hash_disco_sha1(const Stanza &stanza) { std::string s(""); const Stanza *query = stanza.get_child("query", DISCO_INFO_NS); std::vector identities = query->get_children("identity", ""); std::sort(identities.begin(), identities.end(), [](const XmlNode *a, const XmlNode *b) { const std::string category_a = a->get_tag("category"); const std::string category_b = b->get_tag("category"); const int category_compare = category_a > category_b; if (category_compare != 0) return category_compare; const std::string type_a = a->get_tag("type"); const std::string type_b = b->get_tag("type"); const int type_compare = type_a > type_b; return type_compare; }); for (const XmlNode *identity : identities) { const std::string category = identity->get_tag("category"); const std::string type = identity->get_tag("type"); const std::string name = identity->get_tag("name"); s += category + "/" + type + "/" /* + lang + */ "/" + name + "<"; } std::vector features = query->get_children("feature", ""); std::sort(features.begin(), features.end(), [](const XmlNode *a, const XmlNode *b) { const std::string var_a = a->get_tag("var"); const std::string var_b = b->get_tag("var"); const int var_compare = var_a > var_b; return var_compare; }); for (const XmlNode *feature : features) { const std::string var = feature->get_tag("var"); s += var + "<"; } const std::string hashed = sha1(s); const std::string encoded = base64::encode(hashed); return encoded; } } // namespace Xmpp