bool AuthContext::SetHashFileList(const std::wstring &theCommunity, const HashFileList &theList) { AutoCrit aCrit(mDataCrit); AuthLoginCommunityData &aData = mCommunityMap[theCommunity]; aData.mSimpleHash.erase(); aData.mKeyedHashData.erase(); MD5 aSimpleHash; MD5 aHashSection; int curHashSectionPos = 0; HashFileList::const_iterator anItr = theList.begin(); while(anItr!=theList.end()) { FILE *aFile = fopen(anItr->c_str(),"rb"); if(aFile==NULL) return false; ++anItr; const unsigned int HASH_CHUNK_SIZE = 16384; char aFileBuf[HASH_CHUNK_SIZE]; while(!feof(aFile)) { int aNumRead = fread(aFileBuf,1,HASH_CHUNK_SIZE-curHashSectionPos,aFile); if(aNumRead>0) { curHashSectionPos+=aNumRead; aSimpleHash.Update(aFileBuf,aNumRead); aHashSection.Update(aFileBuf,aNumRead); unsigned char aHashSectionBuf[16]; if(curHashSectionPos==HASH_CHUNK_SIZE || (feof(aFile) && anItr==theList.end())) { curHashSectionPos = 0; aHashSection.Digest(aHashSectionBuf); aData.mKeyedHashData.append(aHashSectionBuf,16); aHashSection.Reset(); } } } fclose(aFile); } unsigned char aSimpleHashBuf[16]; aSimpleHash.Digest(aSimpleHashBuf); aData.mSimpleHash.assign(aSimpleHashBuf,16); return true; }
inline void TestMD5() { // echo -n 'qwertyuiopqwertyuiopasdfghjklasdfghjkl' | md5sum char b[] = "qwertyuiopqwertyuiopasdfghjklasdfghjkl"; MD5 r; r.Update((const unsigned char*)b, 15); r.Update((const unsigned char*)b + 15, strlen(b) - 15); char rs[33]; Stroka s(r.End(rs)); s.to_lower(); UNIT_ASSERT_EQUAL(s, Stroka("3ac00dd696b966fd74deee3c35a59d8f")); }
bool RelaxNGValidator::LoadGrammar(const std::string& grammar) { shared_ptr<RelaxNGSchema> schema; { CScopeLock lock(g_SchemaCacheLock); std::map<std::string, shared_ptr<RelaxNGSchema> >::iterator it = g_SchemaCache.find(grammar); if (it == g_SchemaCache.end()) { schema = shared_ptr<RelaxNGSchema>(new RelaxNGSchema(grammar)); g_SchemaCache[grammar] = schema; } else { schema = it->second; } } m_Schema = schema->m_Schema; if (!m_Schema) return false; MD5 hash; hash.Update((const u8*)grammar.c_str(), grammar.length()); m_Hash = hash; return true; }
/** * Creates MD5 hash key from skeletons.xml info and COLLADA converter version, * used to invalidate cached .pmd/psas * * @param[out] hash resulting MD5 hash * @param[out] version version passed to CCacheLoader, used if code change should force * cache invalidation */ void PrepareCacheKey(MD5& hash, u32& version) { // Add converter version to the hash version = COLLADA_CONVERTER_VERSION; // Cache the skeleton files hash data if (m_skeletonHashInvalidated) { VfsPaths paths; if (vfs::GetPathnames(m_VFS, L"art/skeletons/", L"*.xml", paths) != INFO::OK) { LOGWARNING("Failed to load skeleton definitions"); return; } // Sort the paths to not invalidate the cache if mods are mounted in different order // (No need to stable_sort as the VFS gurantees that we have no duplicates) std::sort(paths.begin(), paths.end()); // We need two u64s per file m_skeletonHashes.clear(); m_skeletonHashes.reserve(paths.size()*2); CFileInfo fileInfo; for (const VfsPath& path : paths) { // This will cause an assertion failure if *it doesn't exist, // because fileinfo is not a NULL pointer, which is annoying but that // should never happen, unless there really is a problem if (m_VFS->GetFileInfo(path, &fileInfo) != INFO::OK) { LOGERROR("Failed to stat '%s' for DAE caching", path.string8()); } else { m_skeletonHashes.push_back((u64)fileInfo.MTime() & ~1); //skip lowest bit, since zip and FAT don't preserve it m_skeletonHashes.push_back((u64)fileInfo.Size()); } } // Check if we were able to load any skeleton files if (m_skeletonHashes.empty()) LOGERROR("Failed to stat any skeleton definitions for DAE caching"); // We can continue, something else will break if we try loading a skeletal model m_skeletonHashInvalidated = false; } for (const u64& h : m_skeletonHashes) hash.Update((const u8*)&h, sizeof(h)); }
VfsPath CCacheLoader::LooseCachePath(const VfsPath& sourcePath, const MD5& initialHash, u32 version) { CFileInfo fileInfo; if (m_VFS->GetFileInfo(sourcePath, &fileInfo) < 0) { debug_warn(L"source file disappeared"); // this should never happen return VfsPath(); } u64 mtime = (u64)fileInfo.MTime() & ~1; // skip lowest bit, since zip and FAT don't preserve it u64 size = (u64)fileInfo.Size(); // Construct a hash of the file data and settings. MD5 hash = initialHash; hash.Update((const u8*)&mtime, sizeof(mtime)); hash.Update((const u8*)&size, sizeof(size)); hash.Update((const u8*)&version, sizeof(version)); // these are local cached files, so we don't care about endianness etc // Use a short prefix of the full hash (we don't need high collision-resistance), // converted to hex u8 digest[MD5::DIGESTSIZE]; hash.Final(digest); std::wstringstream digestPrefix; digestPrefix << std::hex; for (size_t i = 0; i < 8; ++i) digestPrefix << std::setfill(L'0') << std::setw(2) << (int)digest[i]; // Get the mod path OsPath path; m_VFS->GetRealPath(sourcePath, path); // Construct the final path return VfsPath("cache") / path_name_only(path.BeforeCommon(sourcePath).Parent().string().c_str()) / sourcePath.ChangeExtension(sourcePath.Extension().string() + L"." + digestPrefix.str() + m_FileExtension); }
void CTextureConverter::Settings::Hash(MD5& hash) { hash.Update((const u8*)&format, sizeof(format)); hash.Update((const u8*)&mipmap, sizeof(mipmap)); hash.Update((const u8*)&normal, sizeof(normal)); hash.Update((const u8*)&alpha, sizeof(alpha)); hash.Update((const u8*)&filter, sizeof(filter)); hash.Update((const u8*)&kaiserWidth, sizeof(kaiserWidth)); hash.Update((const u8*)&kaiserAlpha, sizeof(kaiserAlpha)); hash.Update((const u8*)&kaiserStretch, sizeof(kaiserStretch)); }