123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmUuid.h"
- #include "cmCryptoHash.h"
- #include <string.h>
- cmUuid::cmUuid()
- {
- Groups.push_back(4);
- Groups.push_back(2);
- Groups.push_back(2);
- Groups.push_back(2);
- Groups.push_back(6);
- }
- std::string cmUuid::FromMd5(std::vector<unsigned char> const& uuidNamespace,
- std::string const& name) const
- {
- std::vector<unsigned char> hashInput;
- this->CreateHashInput(uuidNamespace, name, hashInput);
- cmCryptoHash md5(cmCryptoHash::AlgoMD5);
- md5.Initialize();
- md5.Append(&hashInput[0], hashInput.size());
- std::vector<unsigned char> digest = md5.Finalize();
- return this->FromDigest(&digest[0], 3);
- }
- std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
- std::string const& name) const
- {
- std::vector<unsigned char> hashInput;
- this->CreateHashInput(uuidNamespace, name, hashInput);
- cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
- sha1.Initialize();
- sha1.Append(&hashInput[0], hashInput.size());
- std::vector<unsigned char> digest = sha1.Finalize();
- return this->FromDigest(&digest[0], 5);
- }
- void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
- std::string const& name,
- std::vector<unsigned char>& output) const
- {
- output = uuidNamespace;
- if (!name.empty()) {
- output.resize(output.size() + name.size());
- memcpy(&output[0] + uuidNamespace.size(), name.c_str(), name.size());
- }
- }
- std::string cmUuid::FromDigest(const unsigned char* digest,
- unsigned char version) const
- {
- typedef unsigned char byte_t;
- byte_t uuid[16] = { 0 };
- memcpy(uuid, digest, 16);
- uuid[6] &= 0xF;
- uuid[6] |= byte_t(version << 4);
- uuid[8] &= 0x3F;
- uuid[8] |= 0x80;
- return this->BinaryToString(uuid);
- }
- bool cmUuid::StringToBinary(std::string const& input,
- std::vector<unsigned char>& output) const
- {
- output.clear();
- output.reserve(16);
- if (input.length() != 36) {
- return false;
- }
- size_t index = 0;
- for (size_t i = 0; i < this->Groups.size(); ++i) {
- if (i != 0 && input[index++] != '-') {
- return false;
- }
- size_t digits = this->Groups[i] * 2;
- if (!StringToBinaryImpl(input.substr(index, digits), output)) {
- return false;
- }
- index += digits;
- }
- return true;
- }
- std::string cmUuid::BinaryToString(const unsigned char* input) const
- {
- std::string output;
- size_t inputIndex = 0;
- for (size_t i = 0; i < this->Groups.size(); ++i) {
- if (i != 0) {
- output += '-';
- }
- size_t bytes = this->Groups[i];
- for (size_t j = 0; j < bytes; ++j) {
- unsigned char byte = input[inputIndex++];
- output += this->ByteToHex(byte);
- }
- }
- return output;
- }
- std::string cmUuid::ByteToHex(unsigned char byte) const
- {
- std::string result;
- for (int i = 0; i < 2; ++i) {
- unsigned char rest = byte % 16;
- byte /= 16;
- char c = (rest < 0xA) ? char('0' + rest) : char('a' + (rest - 0xA));
- result = c + result;
- }
- return result;
- }
- bool cmUuid::StringToBinaryImpl(std::string const& input,
- std::vector<unsigned char>& output) const
- {
- if (input.size() % 2) {
- return false;
- }
- for (size_t i = 0; i < input.size(); i += 2) {
- char c1 = 0;
- if (!IntFromHexDigit(input[i], c1)) {
- return false;
- }
- char c2 = 0;
- if (!IntFromHexDigit(input[i + 1], c2)) {
- return false;
- }
- output.push_back(char(c1 << 4 | c2));
- }
- return true;
- }
- bool cmUuid::IntFromHexDigit(char input, char& output) const
- {
- if (input >= '0' && input <= '9') {
- output = char(input - '0');
- return true;
- }
- if (input >= 'a' && input <= 'f') {
- output = char(input - 'a' + 0xA);
- return true;
- }
- if (input >= 'A' && input <= 'F') {
- output = char(input - 'A' + 0xA);
- return true;
- }
- return false;
- }
|