📄 hash.cpp
字号:
/*
This file is part of KCeasy (http://www.kceasy.com)
Copyright (C) 2002-2004 Markus Kern <mkern@kceasy.com>
This program is free 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 2
of the License, or (at your option) any later version.
This program 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.
*/
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Hash.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
namespace KCeasyEngine {
// List specifying urn encodings.
// Note that the names are in giFT capitalization while RFC 2141 specifies
// case insensitivity for URNs.
// We really shouldn't have to deal with this in the FE.
static const struct
{
const char* AlgoName;
THashEncoding Encoding;
} UrnEncodings[] =
{
{ "MD5", HASHENC_BASE16 },
{ "SHA1", HASHENC_BASE32 },
{ "FTH", HASHENC_BASE64 },
{ "kzhash", HASHENC_BASE16 },
{ NULL, HASHENC_UNKNOWN }
};
// class THashAlgo
THashAlgo::THashAlgo(const THashAlgo* Algo)
{
Name = Algo->Name;
Encoding = Algo->Encoding;
}
THashAlgo::THashAlgo(const string& Name, THashEncoding Encoding)
{
this->Name = Name;
this->Encoding = Encoding;
}
// class THashAlgoSet
THashAlgoSet::THashAlgoSet()
{
}
THashAlgoSet::THashAlgoSet(const THashAlgoSet* org)
{
*this = *org;
}
THashAlgoSet::~THashAlgoSet()
{
Clear();
}
THashAlgo* THashAlgoSet::GetAlgo(const string& Name) const
{
for(Iterator itr = Begin(); itr != End(); ++itr)
if((*itr)->GetName() == Name)
return (*itr);
return NULL;
}
THashAlgo* THashAlgoSet::GetFirstAlgo() const
{
if(Algos.empty())
return NULL;
return Algos.front();
}
void THashAlgoSet::AddAlgo(THashAlgo* Algo)
{
RemoveAlgo(Algo->GetName());
Algos.push_back(Algo);
}
bool THashAlgoSet::AddAlgo(const string Name, THashEncoding Encoding)
{
RemoveAlgo(Name);
THashAlgo* Algo;
if((Algo = new THashAlgo(Name,Encoding)) != NULL) {
Algos.push_back(Algo);
return true;
}
return false;
}
bool THashAlgoSet::RemoveAlgo(const string& Name)
{
list<THashAlgo*>::iterator itr = Algos.begin();
for(; itr != Algos.end(); ++itr) {
if((*itr)->GetName() == Name) {
delete (*itr);
list<THashAlgo*>::iterator end = itr;
Algos.erase(itr,++end);
return true;
}
}
return false;
}
void THashAlgoSet::Clear()
{
while(!Algos.empty()) {
delete Algos.front();
Algos.pop_front();
}
}
bool THashAlgoSet::Equals(const THashAlgoSet* Cmp) const
{
THashAlgo* CmpAlgo;
for(Iterator itr = Begin(); itr != End(); ++itr) {
if((CmpAlgo = Cmp->GetAlgo((*itr)->GetName())) != NULL) {
if(CmpAlgo->Equals(*itr))
return true;
}
}
return false;
}
THashAlgoSet& THashAlgoSet::operator=(const THashAlgoSet& Org)
{
Clear();
for(Iterator itr = Org.Begin(); itr != Org.End(); ++itr)
AddAlgo((*itr)->GetName(),(*itr)->GetEncoding());
return *this;
}
// class THash
THash::THash()
: Algo(NULL)
{
Algo = new THashAlgo("",HASHENC_UNKNOWN);
}
THash::THash(const THash* org)
: Algo(NULL)
{
*this = *org;
}
THash::THash(const string& Name, THashEncoding Encoding, const string& EncStr)
: Algo(NULL),
EncodedHash(NULL)
{
SetEncoded(Name, Encoding, EncStr);
}
THash::~THash()
{
delete Algo;
}
string THash::GetEncoded() const
{
return EncodedHash;
}
bool THash::SetEncoded(const string& Name, THashEncoding Encoding, const string& EncStr)
{
delete Algo;
if((Algo = new THashAlgo(Name,Encoding)) != NULL) {
EncodedHash = EncStr;
return true;
}
return false;
}
string THash::GetUrn() const
{
string Urn("urn:");
Urn += string_tolower(GetName()) + ":";
Urn += EncodedHash;
return Urn;
}
bool THash::SetUrn(const string& Urn)
{
string Name;
int pos, i;
if(Urn.substr(0,4) != "urn:")
return false;
if((pos = Urn.find(':',4)) == -1)
return false;
Name = Urn.substr(4,pos - 4);
pos++;
// lookup encoding
for(i=0; UrnEncodings[i].AlgoName; i++)
if(Name == UrnEncodings[i].AlgoName)
break;
return SetEncoded(Name,UrnEncodings[i].Encoding,Urn.substr(pos).c_str());
}
string THash::GetGiftHash() const
{
string GiftHash;
int i;
// lookup encoding for right name casing
for(i=0; UrnEncodings[i].AlgoName; i++)
if(GetName() == UrnEncodings[i].AlgoName)
break;
if(UrnEncodings[i].AlgoName == NULL)
return "";
GiftHash = UrnEncodings[i].AlgoName;
GiftHash += string(":") + EncodedHash;
return GiftHash;
}
bool THash::SetGiftHash(const string& GiftHash)
{
string Name;
int pos, i;
if((pos = GiftHash.find(':')) == -1)
return false;
Name = GiftHash.substr(0,pos);
pos++;
// lookup encoding
for(i=0; UrnEncodings[i].AlgoName; i++)
if(Name == UrnEncodings[i].AlgoName)
break;
if(UrnEncodings[i].AlgoName == NULL)
return false;
return SetEncoded(UrnEncodings[i].AlgoName,
UrnEncodings[i].Encoding,
GiftHash.substr(pos).c_str());
}
bool THash::Equals(const THash* Cmp) const
{
return (Algo->Equals(Cmp->Algo) &&
EncodedHash == Cmp->EncodedHash);
}
THash& THash::operator=(const THash& Org)
{
delete Algo;
Algo = new THashAlgo(Org.Algo);
EncodedHash = Org.EncodedHash;
return *this;
}
// class THashSet
THashSet::THashSet()
{
}
THashSet::THashSet(const THashSet* org)
{
*this = *org;
}
THashSet::~THashSet()
{
Clear();
}
THash* THashSet::GetHash(const string& Name) const
{
for(Iterator itr = Begin(); itr != End(); ++itr)
if((*itr)->GetName() == Name)
return (*itr);
return NULL;
}
THash* THashSet::GetFirstHash() const
{
if(Hashes.empty())
return NULL;
return Hashes.front();
}
void THashSet::AddHash(THash* Hash)
{
RemoveHash(Hash->GetName());
Hashes.push_back(Hash);
}
bool THashSet::AddGiftHash(const string& GiftHash)
{
THash* Hash = new THash();
if(Hash->SetGiftHash(GiftHash)) {
AddHash(Hash);
return true;
}
delete Hash;
return false;
}
bool THashSet::RemoveHash(const string& Name)
{
list<THash*>::iterator itr = Hashes.begin();
for(; itr != Hashes.end(); ++itr) {
if((*itr)->GetName() == Name) {
delete (*itr);
list<THash*>::iterator end = itr;
Hashes.erase(itr,++end);
return true;
}
}
return false;
}
void THashSet::JoinHashSet(const THashSet* HashSet)
{
Iterator itr = HashSet->Begin();
for(;itr != HashSet->End(); ++itr) {
// only add hashes if the algo is not yet present
if(GetHash((*itr)->GetName()) == NULL)
AddHash(new THash(*itr));
}
}
void THashSet::Clear()
{
while(!Hashes.empty()) {
delete Hashes.front();
Hashes.pop_front();
}
}
// returns true if Hash is in set
bool THashSet::Contains(const THash* Hash) const
{
THash* CmpHash;
if((CmpHash = GetHash(Hash->GetName())) != NULL && CmpHash->Equals(Hash))
return true;
return false;
}
// return true of at least one hash matches and there are no others which contradict
bool THashSet::Equals(const THashSet* Cmp) const
{
// optimize the common one-one case for search results
if(Hashes.size() == 1 && Cmp->Hashes.size() == 1)
return Hashes.front()->Equals(Cmp->Hashes.front());
bool Match = false;
THash* CmpHash;
for(Iterator itr = Begin(); itr != End(); ++itr) {
if((CmpHash = Cmp->GetHash((*itr)->GetName())) != NULL) {
if(!(*itr)->Equals(CmpHash))
return false;
Match = true;
}
}
return Match;
}
THashSet& THashSet::operator=(const THashSet& Org)
{
Clear();
for(Iterator itr = Org.Begin(); itr != Org.End(); ++itr)
AddHash(new THash(*itr));
return *this;
}
string THashSet::GetBitziUrl()
{
THash* Hash = NULL;
string Url = "";
// create bitzi url with high lookup probability
// best order according to http://bitzi.com/stat/tag seems to be:
// sha1, kzhash, md5, sig2dat
if ((Hash = GetHash("SHA1")) && Hash->GetEncoding() == HASHENC_BASE32) {
Url = "http://bitzi.com/lookup/" + Hash->GetEncoded();
} else if ((Hash = GetHash("kzhash")) && Hash->GetEncoding() == HASHENC_BASE16) {
Url = "http://bitzi.com/lookup/kzhash:" + Hash->GetEncoded();
} else if ((Hash = GetHash("MD5")) && Hash->GetEncoding() == HASHENC_BASE16) {
Url = "http://bitzi.com/lookup/md5:" + Hash->GetEncoded();
} else if ((Hash = GetHash("FTH")) && Hash->GetEncoding() == HASHENC_BASE64) {
Url = "http://bitzi.com/lookup/sig2dat:" + Hash->GetEncoded();
}
return Url;
}
} // namespace KCeasyEngine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -