diff --git a/Foundation/include/Poco/DigestEngine.h b/Foundation/include/Poco/DigestEngine.h index 844b65f9b..78ed1feb7 100644 --- a/Foundation/include/Poco/DigestEngine.h +++ b/Foundation/include/Poco/DigestEngine.h @@ -1,7 +1,7 @@ // // DigestEngine.h // -// $Id: //poco/svn/Foundation/include/Poco/DigestEngine.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/DigestEngine.h#3 $ // // Library: Foundation // Package: Crypt @@ -85,6 +85,9 @@ public: static std::string digestToHex(const Digest& bytes); /// Converts a message digest into a string of hexadecimal numbers. + static Digest digestFromHex(const std::string& digest); + /// Converts a string created by digestToHex back to its Digest presentation + protected: virtual void updateImpl(const void* data, unsigned length) = 0; /// Updates the digest with the given data. Must be implemented diff --git a/Foundation/src/DigestEngine.cpp b/Foundation/src/DigestEngine.cpp index 6616b384a..7c5691184 100644 --- a/Foundation/src/DigestEngine.cpp +++ b/Foundation/src/DigestEngine.cpp @@ -1,7 +1,7 @@ // // DigestEngine.cpp // -// $Id: //poco/svn/Foundation/src/DigestEngine.cpp#2 $ +// $Id: //poco/Main/Foundation/src/DigestEngine.cpp#11 $ // // Library: Foundation // Package: Crypt @@ -35,6 +35,7 @@ #include "Poco/DigestEngine.h" +#include "Poco/Exception.h" namespace Poco { @@ -65,4 +66,39 @@ std::string DigestEngine::digestToHex(const Digest& bytes) } +DigestEngine::Digest DigestEngine::digestFromHex(const std::string& digest) +{ + if (digest.size() % 2 != 0) + throw DataFormatException(); + Digest result; + result.reserve(digest.size()/2); + for (std::size_t i = 0; i < digest.size(); ++i) + { + int c = 0; + // first upper 4 bits + if (digest[i] >= '0' && digest[i] <= '9') + c = digest[i] - '0'; + else if (digest[i] >= 'a' && digest[i] <= 'f') + c = digest[i] - 'a'+10; + else if (digest[i] >= 'A' && digest[i] <= 'F') + c = digest[i] - 'A'+10; + else + throw DataFormatException(); + c <<= 4; + ++i; + if (digest[i] >= '0' && digest[i] <= '9') + c += digest[i] - '0'; + else if (digest[i] >= 'a' && digest[i] <= 'f') + c += digest[i] - 'a'+10; + else if (digest[i] >= 'A' && digest[i] <= 'F') + c += digest[i] - 'A'+10; + else + throw DataFormatException(); + + result.push_back(static_cast(c)); + } + return result; +} + + } // namespace Poco diff --git a/Foundation/testsuite/src/DigestStreamTest.cpp b/Foundation/testsuite/src/DigestStreamTest.cpp index de42b55eb..9f2f559fd 100644 --- a/Foundation/testsuite/src/DigestStreamTest.cpp +++ b/Foundation/testsuite/src/DigestStreamTest.cpp @@ -1,7 +1,7 @@ // // DigestStreamTest.cpp // -// $Id: //poco/svn/Foundation/testsuite/src/DigestStreamTest.cpp#2 $ +// $Id: //poco/Main/Foundation/testsuite/src/DigestStreamTest.cpp#10 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -93,6 +93,15 @@ void DigestStreamTest::testOutputStream2() } +void DigestStreamTest::testToFromHex() +{ + std::string digest("c3fcd3d76192e4007dfb496cca67e13b"); + Poco::DigestEngine::Digest dig = DigestEngine::digestFromHex(digest); + std::string digest2 = DigestEngine::digestToHex(dig); + assert (digest == digest2); +} + + void DigestStreamTest::setUp() { } @@ -110,6 +119,7 @@ CppUnit::Test* DigestStreamTest::suite() CppUnit_addTest(pSuite, DigestStreamTest, testInputStream); CppUnit_addTest(pSuite, DigestStreamTest, testOutputStream1); CppUnit_addTest(pSuite, DigestStreamTest, testOutputStream2); + CppUnit_addTest(pSuite, DigestStreamTest, testToFromHex); return pSuite; } diff --git a/Foundation/testsuite/src/DigestStreamTest.h b/Foundation/testsuite/src/DigestStreamTest.h index e465666f3..36b039576 100644 --- a/Foundation/testsuite/src/DigestStreamTest.h +++ b/Foundation/testsuite/src/DigestStreamTest.h @@ -1,7 +1,7 @@ // // DigestStreamTest.h // -// $Id: //poco/svn/Foundation/testsuite/src/DigestStreamTest.h#2 $ +// $Id: //poco/Main/Foundation/testsuite/src/DigestStreamTest.h#9 $ // // Definition of the DigestStreamTest class. // @@ -49,6 +49,7 @@ public: void testInputStream(); void testOutputStream1(); void testOutputStream2(); + void testToFromHex(); void setUp(); void tearDown();