Browse Source

加入mysql、配置模块、dockerfile、docker_compose等

master
Your Name 3 years ago
parent
commit
abd364293f
  1. 3
      .vscode/settings.json
  2. 7
      CMakeLists.txt
  3. 2
      README.md
  4. 1
      cmake/FindMYSQL.cmake
  5. BIN
      docker/3rdparty/ZLToolKit.tar.gz
  6. 0
      docker/Dockerfile
  7. 34
      docker/Dockerfile.satellite
  8. 20
      docker/docker-compose.yml
  9. BIN
      lib/libmodels.so
  10. 14
      modules/CMakeLists.txt
  11. 76
      modules/Disposition/include/Disposition.hpp
  12. 74
      modules/Disposition/src/Disposition.cpp
  13. 6
      modules/TcpProxySession/include/TcpProxySession.hpp
  14. 18
      modules/TcpProxySession/src/TcpProxySession.cpp
  15. 31
      modules/UserApp/include/UserApp.hpp
  16. 14
      modules/UserApp/src/UserApp.cpp
  17. 39
      modules/dataType/include/NonCopyable.hpp
  18. 61
      modules/md5/include/md5.hpp
  19. 330
      modules/md5/src/md5.cpp

3
.vscode/settings.json vendored

@ -57,6 +57,7 @@
"typeindex": "cpp", "typeindex": "cpp",
"typeinfo": "cpp", "typeinfo": "cpp",
"valarray": "cpp", "valarray": "cpp",
"string": "cpp" "string": "cpp",
"future": "cpp"
} }
} }

7
CMakeLists.txt

@ -2,8 +2,11 @@ if(" ${CMAKE_SOURCE_DIR}" STREQUAL " ${CMAKE_BINARY_DIR}")
message(FATAL_ERROR "Please create a separate directory for build files.") message(FATAL_ERROR "Please create a separate directory for build files.")
endif() endif()
cmake_minimum_required(VERSION 3.6) cmake_minimum_required(VERSION 3.6)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
project(ISNS C CXX) project(ISNS C CXX)
set(CMAKE_VERBOSE_MAKEFILE OFF) set(CMAKE_VERBOSE_MAKEFILE OFF)
@ -15,6 +18,8 @@ if(build_modules)
add_subdirectory(modules) add_subdirectory(modules)
endif() endif()
set(ENABLE_MYSQL ON CACHE BOOL "enable mysql")
##OpenCV ##OpenCV
if(WITH_OPENCV) if(WITH_OPENCV)
if(CMAKE_TOOLCHAIN_FILE) if(CMAKE_TOOLCHAIN_FILE)
@ -69,6 +74,8 @@ endif()
include_directories(${PROJECT_SOURCE_DIR}/3rdparty/rapidjson/include/) include_directories(${PROJECT_SOURCE_DIR}/3rdparty/rapidjson/include/)
include_directories(/usr/local/include/hv) include_directories(/usr/local/include/hv)
include_directories(${PROJECT_SOURCE_DIR}/modules/UserApp/include/) include_directories(${PROJECT_SOURCE_DIR}/modules/UserApp/include/)
include_directories(${PROJECT_SOURCE_DIR}/modules/dataType/include/)
include_directories(${PROJECT_SOURCE_DIR}/modules/Disposition/include/)
include_directories(${PROJECT_SOURCE_DIR}/modules/TcpProxySession/include/) include_directories(${PROJECT_SOURCE_DIR}/modules/TcpProxySession/include/)

2
README.md

@ -1,6 +1,6 @@
## Satellite ## Satellite
*** ***
> Satellite > satellite

1
cmake/FindMYSQL.cmake

@ -31,6 +31,7 @@ else(WIN32)
$ENV{MYSQL_INCLUDE_DIR} $ENV{MYSQL_INCLUDE_DIR}
$ENV{MYSQL_DIR}/include $ENV{MYSQL_DIR}/include
/usr/local/mysql/include /usr/local/mysql/include
/opt/mysql/mysql/include
PATH_SUFFIXES PATH_SUFFIXES
mysql mysql
) )

BIN
docker/3rdparty/ZLToolKit.tar.gz vendored

Binary file not shown.

0
docker/Dockerfile

34
docker/Dockerfile.satellite

@ -0,0 +1,34 @@
FROM ubuntu:16.04
MAINTAINER <lishengyin, 1348640163@qq.com>
ARG with_satellite_code=yes
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
cmake \
libmysqlclient-dev \
libssl-dev \
libgoogle-glog-dev \
libsqlite3-dev \
sqlite3 \
uuid-dev
# 拷贝文件
COPY ./3rdparty/ZLToolKit.tar.gz /root
COPY ./3rdparty/opencv.tar.gz /root
COPY ./3rdparty/kafka.tar.gz /root
# install zltoolkit
RUN cd /root/ && tar -zxvf ZLToolKit.tar.gz
RUN cp -rf /root/ZLToolKit/lib/* /usr/lib/
RUN cp -rf /root/ZLToolKit/include/* /usr/include/
RUN if [ "$with_cnstream_code" = "yes" ]; then \
cd /root && git clone http://120.79.157.137:80/lishengyin/Satellite.git Satellite && \
cd /root/Satellite && mkdir build && cd build &&\
cmake ..&& make -j; \
fi
WORKDIR /root

20
docker/docker-compose.yml

@ -0,0 +1,20 @@
version: '2'
services:
satellite:
build:
context: $PWD/
dockerfile: Dockerfile.satellite
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
network_mode: "host"
privileged: true
ports:
- "7400:7400"
tty: true
environment:
- DISPLAY:$DISPLAY
ipc: "host"
pid: "host"
command: /bin/bash -c "cd /root/Satellite/build && ./main"

BIN
lib/libmodels.so

Binary file not shown.

14
modules/CMakeLists.txt

@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.6)
set(INS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) set(INS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(NOT COMPILER_SUPPORTS_CXX11) if(NOT COMPILER_SUPPORTS_CXX11)
@ -23,6 +25,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_REENTRANT -fPIC -Wall -Wer
option(build_UserApp "build module UserApp " ON) option(build_UserApp "build module UserApp " ON)
option(build_TcpProxySession "build module TcpProxySession" ON) option(build_TcpProxySession "build module TcpProxySession" ON)
option(build_dataType "build module dataType" ON) option(build_dataType "build module dataType" ON)
option(build_Disposition "build module Disposition" ON)
option(build_md5 "build module md5" ON)
# ---[ 3rdparty # ---[ 3rdparty
set(3RDPARTY_LIBS "") set(3RDPARTY_LIBS "")
@ -74,6 +78,16 @@ if(build_dataType)
include_directories(${PROJECT_SOURCE_DIR}/modules/dataType/src) include_directories(${PROJECT_SOURCE_DIR}/modules/dataType/src)
install(DIRECTORY dataType/include/ DESTINATION include) install(DIRECTORY dataType/include/ DESTINATION include)
endif() endif()
if(build_Disposition)
list(APPEND module_list Disposition)
include_directories(${PROJECT_SOURCE_DIR}/modules/Disposition/src)
install(DIRECTORY Disposition/include/ DESTINATION include)
endif()
if(build_md5)
list(APPEND module_list md5)
include_directories(${PROJECT_SOURCE_DIR}/modules/md5/src)
install(DIRECTORY md5/include/ DESTINATION include)
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(/usr/local/include/hv) include_directories(/usr/local/include/hv)

76
modules/Disposition/include/Disposition.hpp

@ -0,0 +1,76 @@
/*
* @Description:
* @Version: 1.0
* @Autor: lishengyin
* @Date: 2022-04-12 08:37:45
* @LastEditors: lishengyin
* @LastEditTime: 2022-04-12 10:16:08
*/
#ifndef __DISPOSITION_HPP_
#define __DISPOSITION_HPP_
#include <iostream>
#include "NonCopyable.hpp"
#include <map>
#include "login.hpp"
#include "Util/logger.h"
#include "Util/NoticeCenter.h"
#include "Poller/EventPoller.h"
#include "Util/SqlPool.h"
#include "Network/TcpClient.h"
#include "Poller/Timer.h"
#include <vector>
using namespace std;
using namespace toolkit;
class Disposition:private NonCopyable
{
private:
Disposition(){}
public:
using Ptr = std::shared_ptr<Disposition>;
~Disposition(){}
/**
* @description: ptr
* @param {*}
* @return {*}
*/
static std::shared_ptr<Disposition> getPtr();
/**
* @description:
* @param {*}
* @return {*}
*/
bool Init();
/**
* @description:
* @param {*}
* @return {*}
*/
bool getUserValidity(Login& login);
/**
* @description:
* @param {*}
* @return {*}
*/
bool getUserInfos();
protected:
std::string mysqlIP = "101.35.200.152";
int port = 13306;
map<std::string, std::string> LoginInfos;
};
#endif

74
modules/Disposition/src/Disposition.cpp

@ -0,0 +1,74 @@
/*
* @Description:
* @Version: 1.0
* @Autor: lishengyin
* @Date: 2022-04-12 08:37:49
* @LastEditors: lishengyin
* @LastEditTime: 2022-04-12 10:02:49
*/
#include "Disposition.hpp"
#include "md5.hpp"
/**
* @description: ptr
* @param {*}
* @return {*}
*/
std::shared_ptr<Disposition> Disposition::getPtr(){
static std::shared_ptr<Disposition> m_Disposition = nullptr;
if(m_Disposition == nullptr) m_Disposition = std::shared_ptr<Disposition>(new Disposition);
return m_Disposition;
}
/**
* @description:
* @param {*}
* @return {*}
*/
bool Disposition::Init(){
// 链接Mysql
#if defined(SUPPORT_DYNAMIC_TEMPLATE)
//初始化数据
SqlPool::Instance().Init(this->mysqlIP,this->port,"","root",""/*,character*/);
#else
//由于需要编译器对可变参数模板的支持,所以gcc5.0以下一般都不支持,否则编译报错
ErrorL << "your compiler does not support variable parameter templates!" << endl;
return false;
#endif //defined(SUPPORT_DYNAMIC_TEMPLATE)
// 初始化数据库连接池
SqlPool::Instance().setSize(2 + thread::hardware_concurrency());
return true;
}
/**
* @description:
* @param {Login&} login
* @return {*}
*/
bool Disposition::getUserValidity(Login& login){
// 查询表列表
this->getUserInfos();
auto iter = LoginInfos.find(login.usr);
if(iter == LoginInfos.end()) return false;
// md5加密后与数据库的密码做比较
if(md5(login.usr+login.pwd) == iter->second) return true;
return false;
}
/**
* @description:
* @param {*}
* @return {*}
*/
bool Disposition::getUserInfos(){
vector<vector<string>> sqlRet;
SqlWriter sqlSelect("SELECT usr,pwd FROM SatelliteConfigDB.`UserInfos`");
sqlSelect << sqlRet;
for(auto& line : sqlRet){
LoginInfos[line[0]] = line[1];
}
return true;
}

6
modules/TcpProxySession/include/TcpProxySession.hpp

@ -3,8 +3,8 @@
* @Version: 1.0 * @Version: 1.0
* @Autor: lishengyin * @Autor: lishengyin
* @Date: 2022-04-11 17:30:58 * @Date: 2022-04-11 17:30:58
* @LastEditors: Please set LastEditors * @LastEditors: lishengyin
* @LastEditTime: 2022-04-12 00:07:32 * @LastEditTime: 2022-04-12 10:09:31
*/ */
#ifndef __TCPPROXYSESSION_HPP_ #ifndef __TCPPROXYSESSION_HPP_
#define __TCPPROXYSESSION_HPP_ #define __TCPPROXYSESSION_HPP_
@ -24,8 +24,6 @@ using namespace toolkit;
class TcpProxySession; class TcpProxySession;
class TcpProxySession: public TcpSession { class TcpProxySession: public TcpSession {
public: public:
TcpProxySession(const Socket::Ptr &sock) : TcpProxySession(const Socket::Ptr &sock) :

18
modules/TcpProxySession/src/TcpProxySession.cpp

@ -3,29 +3,35 @@
* @Version: 1.0 * @Version: 1.0
* @Autor: lishengyin * @Autor: lishengyin
* @Date: 2022-04-11 17:31:02 * @Date: 2022-04-11 17:31:02
* @LastEditors: Please set LastEditors * @LastEditors: lishengyin
* @LastEditTime: 2022-04-12 00:25:04 * @LastEditTime: 2022-04-12 10:36:29
*/ */
#include "TcpProxySession.hpp" #include "TcpProxySession.hpp"
#include "login.hpp" #include "login.hpp"
#include <algorithm> #include <algorithm>
#include "Disposition.hpp"
static map<std::string, vector<TcpProxySession *>> m_ProxySessions; static map<std::string, vector<TcpProxySession *>> m_ProxySessions;
void TcpProxySession::onRecv(const Buffer::Ptr &buf) { void TcpProxySession::onRecv(const Buffer::Ptr &buf) {
//处理客户端发送过来的数据 //处理客户端发送过来的数据
TraceL << buf->data() << " from port:" << getIdentifier(); // TraceL << buf->data() << " from port:" << getIdentifier();
if(this->alive == false){ if(this->alive == false){
Login login; Login login;
std::string json = buf->data(); std::string json = buf->data();
if(buf->size() > 10 && this->alive == false){ if(buf->size() > 10 && this->alive == false){
auto sendBuf = BufferRaw::create(); auto sendBuf = BufferRaw::create();
if(login.jsonToObject(json)){ if(login.jsonToObject(json)){
sendBuf->assign("login successfully"); if(!Disposition::getPtr()->getUserValidity(login)){
send((Buffer::Ptr &)sendBuf); this->alive = false;
this->alive = true; sendBuf->assign("The account or password is incorrect");
}else{
this->usr = login.usr; this->usr = login.usr;
this->alive = true;
m_ProxySessions[this->usr].push_back(this); m_ProxySessions[this->usr].push_back(this);
sendBuf->assign("login successfully");
}
send((Buffer::Ptr &)sendBuf);
}else { }else {
sendBuf->assign("Not logged in. Please log in"); sendBuf->assign("Not logged in. Please log in");
send((Buffer::Ptr &)sendBuf); send((Buffer::Ptr &)sendBuf);

31
modules/UserApp/include/UserApp.hpp

@ -3,8 +3,8 @@
* @Version: 1.0 * @Version: 1.0
* @Autor: lishengyin * @Autor: lishengyin
* @Date: 2022-04-11 17:12:05 * @Date: 2022-04-11 17:12:05
* @LastEditors: Please set LastEditors * @LastEditors: lishengyin
* @LastEditTime: 2022-04-11 23:12:33 * @LastEditTime: 2022-04-12 10:13:25
*/ */
#ifndef __USERAPP_HPP_ #ifndef __USERAPP_HPP_
#define __USERAPP_HPP_ #define __USERAPP_HPP_
@ -27,6 +27,8 @@
#include "Network/TcpServer.h" #include "Network/TcpServer.h"
#include "Network/TcpSession.h" #include "Network/TcpSession.h"
#include "TcpProxySession.hpp" #include "TcpProxySession.hpp"
#include "Disposition.hpp"
#include "Poller/Timer.h"
using namespace std; using namespace std;
using namespace toolkit; using namespace toolkit;
@ -34,29 +36,6 @@ using namespace toolkit;
#define OK 0 #define OK 0
#define ERR -1 #define ERR -1
// NonCopyAble
class NonCopyable {
protected:
NonCopyable() {};
~NonCopyable() {};
public:
NonCopyable(const NonCopyable&) = delete;
NonCopyable(NonCopyable&&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
NonCopyable& operator=(NonCopyable&&) = delete;
static std::string getDataTime(){
char ctime[80];
time_t rawtime;
struct tm *info;
time(&rawtime);
info = localtime(&rawtime);
strftime(ctime, 80, "%Y-%m-%d %H:%M:%S", info);
std::string DataTime = ctime;
return DataTime;
}
};
class UserApp:private NonCopyable class UserApp:private NonCopyable
{ {
@ -91,8 +70,8 @@ public:
private: private:
std::string appName_; std::string appName_;
int port = 7400; int port = 7400;
TcpServer::Ptr m_tcpServer = nullptr; TcpServer::Ptr m_tcpServer = nullptr;
Timer::Ptr m_timer;
}; };

14
modules/UserApp/src/UserApp.cpp

@ -3,8 +3,8 @@
* @Version: 1.0 * @Version: 1.0
* @Autor: lishengyin * @Autor: lishengyin
* @Date: 2022-04-11 17:12:10 * @Date: 2022-04-11 17:12:10
* @LastEditors: Please set LastEditors * @LastEditors: lishengyin
* @LastEditTime: 2022-04-11 23:58:52 * @LastEditTime: 2022-04-12 10:16:29
*/ */
#include "UserApp.hpp" #include "UserApp.hpp"
@ -23,7 +23,16 @@ std::shared_ptr<UserApp> UserApp::CreateNew(std::string appName){
* @return {*} * @return {*}
*/ */
int8_t UserApp::Init(){ int8_t UserApp::Init(){
if(!Disposition::getPtr()->Init()){
ErrorL << "Disposition Module initialization failed. Procedure" << endl;
return ERR;
}
if(m_tcpServer == nullptr) m_tcpServer = std::shared_ptr<TcpServer>(new TcpServer()); if(m_tcpServer == nullptr) m_tcpServer = std::shared_ptr<TcpServer>(new TcpServer());
// 定时表中数据
this->m_timer = std::make_shared<Timer>(3.0f, [&](){
Disposition::getPtr()->getUserInfos();
return true;
}, nullptr);
return OK; return OK;
} }
@ -34,7 +43,6 @@ int8_t UserApp::Init(){
*/ */
int8_t UserApp::StartTask(){ int8_t UserApp::StartTask(){
this->m_tcpServer->start<TcpProxySession>(this->port); this->m_tcpServer->start<TcpProxySession>(this->port);
return OK; return OK;
} }

39
modules/dataType/include/NonCopyable.hpp

@ -0,0 +1,39 @@
/*
* @Description:
* @Version: 1.0
* @Autor: lishengyin
* @Date: 2022-04-12 10:07:55
* @LastEditors: lishengyin
* @LastEditTime: 2022-04-12 10:08:56
*/
#ifndef __NONCOPYABLE_HPP_
#define __NONCOPYABLE_HPP_
#include <iostream>
using namespace std;
// NonCopyAble
class NonCopyable {
protected:
NonCopyable() {};
~NonCopyable() {};
public:
NonCopyable(const NonCopyable&) = delete;
NonCopyable(NonCopyable&&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
NonCopyable& operator=(NonCopyable&&) = delete;
static std::string getDataTime(){
char ctime[80];
time_t rawtime;
struct tm *info;
time(&rawtime);
info = localtime(&rawtime);
strftime(ctime, 80, "%Y-%m-%d %H:%M:%S", info);
std::string DataTime = ctime;
return DataTime;
}
};
#endif

61
modules/md5/include/md5.hpp

@ -0,0 +1,61 @@
#ifndef BZF_MD5_H
#define BZF_MD5_H
#include <cstring>
#include <iostream>
// a small class for calculating MD5 hashes of strings or byte arrays
// it is not meant to be fast or secure
//
// usage: 1) feed it blocks of uchars with update()
// 2) finalize()
// 3) get hexdigest() string
// or
// MD5(std::string).hexdigest()
//
// assumes that char is 8 bit and int is 32 bit
class MD5
{
public:
typedef unsigned int size_type; // must be 32bit
MD5();
MD5(const std::string& text);
void update(const unsigned char *buf, size_type length);
void update(const char *buf, size_type length);
MD5& finalize();
std::string hexdigest() const;
friend std::ostream& operator<<(std::ostream&, MD5 md5);
private:
void init();
typedef unsigned char uint1; // 8bit
typedef unsigned int uint4; // 32bit
enum {blocksize = 64}; // VC6 won't eat a const static int here
void transform(const uint1 block[blocksize]);
static void decode(uint4 output[], const uint1 input[], size_type len);
static void encode(uint1 output[], const uint4 input[], size_type len);
bool finalized;
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
uint4 state[4]; // digest so far
uint1 digest[16]; // the result
// low level logic operations
static inline uint4 F(uint4 x, uint4 y, uint4 z);
static inline uint4 G(uint4 x, uint4 y, uint4 z);
static inline uint4 H(uint4 x, uint4 y, uint4 z);
static inline uint4 I(uint4 x, uint4 y, uint4 z);
static inline uint4 rotate_left(uint4 x, int n);
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
};
std::string md5(const std::string str);
#endif

330
modules/md5/src/md5.cpp

@ -0,0 +1,330 @@
/* interface header */
#include "md5.hpp"
/* system implementation headers */
#include <cstdio>
// Constants for MD5Transform routine.
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
///////////////////////////////////////////////
// F, G, H and I are basic MD5 functions.
inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
return (x&y) | (~x&z);
}
inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
return (x&z) | (y&~z);
}
inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
return x^y^z;
}
inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
return y ^ (x | ~z);
}
// rotate_left rotates x left n bits.
inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
return (x << n) | (x >> (32-n));
}
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a+ F(b,c,d) + x + ac, s) + b;
}
inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + G(b,c,d) + x + ac, s) + b;
}
inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + H(b,c,d) + x + ac, s) + b;
}
inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + I(b,c,d) + x + ac, s) + b;
}
//////////////////////////////////////////////
// default ctor, just initailize
MD5::MD5()
{
init();
}
//////////////////////////////////////////////
// nifty shortcut ctor, compute MD5 for string and finalize it right away
MD5::MD5(const std::string &text)
{
init();
update(text.c_str(), text.length());
finalize();
}
//////////////////////////////
void MD5::init()
{
finalized=false;
count[0] = 0;
count[1] = 0;
// load magic initialization constants.
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
}
//////////////////////////////
// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
void MD5::decode(uint4 output[], const uint1 input[], size_type len)
{
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
}
//////////////////////////////
// encodes input (uint4) into output (unsigned char). Assumes len is
// a multiple of 4.
void MD5::encode(uint1 output[], const uint4 input[], size_type len)
{
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
output[j] = input[i] & 0xff;
output[j+1] = (input[i] >> 8) & 0xff;
output[j+2] = (input[i] >> 16) & 0xff;
output[j+3] = (input[i] >> 24) & 0xff;
}
}
//////////////////////////////
// apply MD5 algo on a block
void MD5::transform(const uint1 block[blocksize])
{
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
decode (x, block, blocksize);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
// Zeroize sensitive information.
memset(x, 0, sizeof x);
}
//////////////////////////////
// MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block
void MD5::update(const unsigned char input[], size_type length)
{
// compute number of bytes mod 64
size_type index = count[0] / 8 % blocksize;
// Update number of bits
if ((count[0] += (length << 3)) < (length << 3))
count[1]++;
count[1] += (length >> 29);
// number of bytes we need to fill in buffer
size_type firstpart = 64 - index;
size_type i;
// transform as many times as possible.
if (length >= firstpart)
{
// fill buffer first, transform
memcpy(&buffer[index], input, firstpart);
transform(buffer);
// transform chunks of blocksize (64 bytes)
for (i = firstpart; i + blocksize <= length; i += blocksize)
transform(&input[i]);
index = 0;
}
else
i = 0;
// buffer remaining input
memcpy(&buffer[index], &input[i], length-i);
}
//////////////////////////////
// for convenience provide a verson with signed char
void MD5::update(const char input[], size_type length)
{
update((const unsigned char*)input, length);
}
//////////////////////////////
// MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context.
MD5& MD5::finalize()
{
static unsigned char padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (!finalized) {
// Save number of bits
unsigned char bits[8];
encode(bits, count, 8);
// pad out to 56 mod 64.
size_type index = count[0] / 8 % 64;
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
update(padding, padLen);
// Append length (before padding)
update(bits, 8);
// Store state in digest
encode(digest, state, 16);
// Zeroize sensitive information.
memset(buffer, 0, sizeof buffer);
memset(count, 0, sizeof count);
finalized=true;
}
return *this;
}
//////////////////////////////
// return hex representation of digest as string
std::string MD5::hexdigest() const
{
if (!finalized)
return "";
char buf[33];
for (int i=0; i<16; i++)
sprintf(buf+i*2, "%02x", digest[i]);
buf[32]=0;
return std::string(buf);
}
//////////////////////////////
std::ostream& operator<<(std::ostream& out, MD5 md5)
{
return out << md5.hexdigest();
}
//////////////////////////////
std::string md5(const std::string str)
{
MD5 md5 = MD5(str);
return md5.hexdigest();
}
Loading…
Cancel
Save