#include "CCommonTools.h"
#include <QDateTime>
#include <QUuid>
#include <QProcess>
#include <QStringList>
#include <QCryptographicHash>
#include  "logproc.h"
#include <random>
#include <QFileInfo>
#include <QDir>
#include <windows.h>
#include <tlhelp32.h>// for CreateToolhelp32Snapshot
#include <Psapi.h>   // for GetModuleFileNameEx
#include <Dshow.h>




#define FORMAT_PATH(path) path.replace('\\','/').toLower()

#ifdef __GNUC__
    #include <cpuid.h>
#elif defined(_MSC_VER)
    #if _MSC_VER >= 1400
        #include <intrin.h>
    #endif
#else
    #error Only supports MSVC or GCC
#endif



namespace CCommonTools
{
    bool IsWow64()
    {
        bool bRetVal = false;
        SYSTEM_INFO si = { 0 };

        typedef VOID (WINAPI *LPFN_PGNSI) (LPSYSTEM_INFO);

        LPFN_PGNSI pGNSI = (LPFN_PGNSI) GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetNativeSystemInfo");
        if (pGNSI == NULL)
        {
            return false;
        }
        pGNSI(&si);
        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
        si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 )
        {
            bRetVal = true;
        }
        else
        {
             //32 位操作系统
        }
        return bRetVal;
    }

    int getDisplayNumber()
    {		
        int iNumber = 0;
        bool bFlag = true;

        DISPLAY_DEVICE dd;
        ZeroMemory(&dd,sizeof(dd));
        dd.cb =sizeof(dd);

        DEVMODE devMode;
        ZeroMemory(&devMode,sizeof(devMode)); devMode.dmSize=sizeof(devMode);
        do
        {
            bFlag = EnumDisplayDevices(NULL, iNumber,&dd,0);
            bFlag = bFlag && EnumDisplaySettings(dd.DeviceName,ENUM_CURRENT_SETTINGS,&devMode);
            if(bFlag)
            {
                iNumber +=1;
            }
        }
        while(bFlag);
        return iNumber;
    }

    void getcpuid(unsigned int CPUInfo[4], unsigned int InfoType)
    {
    #if defined(__GNUC__)// GCC
        __cpuid(InfoType, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
    #elif defined(_MSC_VER)// MSVC
    #if _MSC_VER >= 1400 //VC2005才支持__cpuid
        __cpuid((int*)(void*)CPUInfo, (int)(InfoType));
    #else //其他使用getcpuidex
        getcpuidex(CPUInfo, InfoType, 0);
    #endif
    #endif
    }
    void getcpuidex(unsigned int CPUInfo[4], unsigned int InfoType, unsigned int ECXValue)
    {
    #if defined(_MSC_VER) // MSVC
    #if defined(_WIN64) // 64位下不支持内联汇编. 1600: VS2010, 据说VC2008 SP1之后才支持__cpuidex.
        __cpuidex((int*)(void*)CPUInfo, (int)InfoType, (int)ECXValue);
    #else
        if (NULL==CPUInfo)  return;
        _asm{
            // load. 读取参数到寄存器.
            mov edi, CPUInfo;
            mov eax, InfoType;
            mov ecx, ECXValue;
            // CPUID
            cpuid;
            // save. 将寄存器保存到CPUInfo
            mov [edi], eax;
            mov [edi+4], ebx;
            mov [edi+8], ecx;
            mov [edi+12], edx;
        }
    #endif
    #endif
    }

    QString get_cpuId()
    {
        QString cpu_id = "";
        unsigned int dwBuf[4]={0};
        unsigned long long ret = 0;
        getcpuid(dwBuf, 1);
        ret = dwBuf[3];
        ret = ret << 32;

        QString str0 = QString::number(dwBuf[3], 16).toUpper();
        QString str0_1 = str0.rightJustified(8,'0');//这一句的意思是前面补0，但是我遇到的情况是这里都填满了
        QString str1 = QString::number(dwBuf[0], 16).toUpper();
        QString str1_1 = str1.rightJustified(8,'0');//这里必须在前面补0，否则不会填满数据
        //cpu_id = cpu_id + QString::number(dwBuf[0], 16).toUpper();
        cpu_id = str0_1 + str1_1;
        return cpu_id;
    }

	QString Arab2Sinogram(int num)
	{
		QStringList lNum = { QString::fromLocal8Bit("零"),
							QString::fromLocal8Bit("一"),
							QString::fromLocal8Bit("二"),
							QString::fromLocal8Bit("三"),
							QString::fromLocal8Bit("四"),
							QString::fromLocal8Bit("五"),
							QString::fromLocal8Bit("六"),
							QString::fromLocal8Bit("七"),
							QString::fromLocal8Bit("八"),
							QString::fromLocal8Bit("九") };
		QStringList lBit = { "", QString::fromLocal8Bit("十"),
							QString::fromLocal8Bit("百"),
							QString::fromLocal8Bit("千") };
		QStringList lTep = { "",
							QString::fromLocal8Bit("万"),
							QString::fromLocal8Bit("亿"),
							QString::fromLocal8Bit("万"),
							QString::fromLocal8Bit("亿"),
							QString::fromLocal8Bit("万"),
							QString::fromLocal8Bit("亿") };
		std::vector<char> input;
		QString output;
		bool bZero = false;

		int n = (int)log10((float)num) + 1;
		for (int i = 0; i < n; i++, num = num / 10)
		{
			input.push_back((char)(num % 10));
		}
		for (int i = n - 1; i >= 0; i--)
		{
			num = input[i];
			if (num == 0)
			{
				bZero = true;
			}
			else if (num > 0 && bZero)
			{
				output += lNum[0];
				bZero = false;
			}
			if (num > 0)
			{
				output += lNum[num];
				output += lBit[(i) % 4];
			}
			if (i % 4 == 0)
			{
				output += lTep[i / 4];
				bZero = true;
			}
		}
		if (output.isEmpty())
		{
			output += lNum[0];
		}

		return output;
	}

    void createDir(QString sDir)
    {
        QFileInfo fileInfo = sDir;
        QDir dir;
        QString sExt = fileInfo.suffix();
        if(sExt.isEmpty())
        {
            dir = QDir(fileInfo.absoluteFilePath());
        }
        else
        {
            dir = QDir(fileInfo.absolutePath());
        }

        if(!dir.exists())
        {
           dir.mkpath(dir.absolutePath());
        }
    }

    QString getUuid()
    {
        QUuid id = QUuid::createUuid();
        QString strId = id.toString();
        strId.replace("-", "");
        strId = strId.mid(1, strId.length() - 2);
        return strId;
    }

    qint64 getTimeStamp()
    {
        QDateTime time = QDateTime::currentDateTime();   //获取当前时间
        uint timeStamp = time.toTime_t();   //将当前时间转为时间戳
        return timeStamp;
    }

    bool isUseRDP()//是否使用远程桌面
    {
        QProcess process;
        QString cmd = QString("qwinsta.exe");
        QStringList sparam;

        process.start(cmd, sparam);
        process.waitForFinished();
        QByteArray qbt = process.readAllStandardOutput();
        QString sInfo = QString::fromLocal8Bit(qbt.data());
//        myDebug()<<sInfo;
        if(sInfo.indexOf("rdp") < 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    QString GetPathByProcessID(DWORD pid)
    {
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
        if (!hProcess)
        {
            //QMessageBox::warning(NULL,"GetPathByProcessID","无权访问该进程");
            return "";
        }
        WCHAR filePath[MAX_PATH];
        DWORD ret= GetModuleFileNameEx(hProcess, NULL, filePath, MAX_PATH) ;
        QString file = QString::fromStdWString( filePath );
        //QMessageBox::warning(NULL,"GetPathByProcessID ret=", QString::number(ret)+":"+file);
        CloseHandle(hProcess);
        return ret==0?"":file;
    }

    void getAllAppNameList(QStringList &appList, QStringList sCheckApps, QStringList sCheckNames)
    {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(pe32);
        HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if(hProcessSnap == INVALID_HANDLE_VALUE)
        {
            return ;
        }
        BOOL bMore = Process32First(hProcessSnap,&pe32);
        while(bMore)
        {
            QString exeName = (QString::fromUtf16(reinterpret_cast<const unsigned short *>(pe32.szExeFile)));
            QString exePath = GetPathByProcessID( pe32.th32ProcessID );
            exePath = FORMAT_PATH( exePath );
            if(!exePath.isEmpty() )
            {                
                for(int i = 0; i < sCheckApps.count(); ++i)
                {
                    if(exeName.toLower().indexOf(sCheckApps[i].toLower()) == 0)
                    {
						if(appList.indexOf(sCheckNames[i]) < 0)
						{ 
							appList.push_back(sCheckNames[i]);
						}
                        
                    }
                }
            }
            bMore = Process32Next(hProcessSnap,&pe32);
        }
        CloseHandle(hProcessSnap);
    }

    int listCameraDevices(std::vector<CameraInfo> &list)
    {
        int deviceCounter = 0;
        HRESULT hr = CoInitialize(NULL);
        if (SUCCEEDED(hr))
        {
            IEnumMoniker *pEnum;

            ICreateDevEnum *pDevEnum;
            HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
                CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

            if (SUCCEEDED(hr))
            {
                // Create an enumerator for the category.
                hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
                if (hr == S_FALSE)
                {
                    hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
                }
                pDevEnum->Release();
            }


            if (SUCCEEDED(hr))
            {
                IMoniker *pMoniker = NULL;

                while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
                {
                    IPropertyBag *pPropBag;
                    HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
                    if (FAILED(hr))
                    {
                        pMoniker->Release();
                        continue;
                    }

                    CameraInfo cam;

                    VARIANT var;
                    VariantInit(&var);

                    // Get description or friendly name.
                    hr = pPropBag->Read(L"Description", &var, 0);
                    if (FAILED(hr))
                    {
                        hr = pPropBag->Read(L"FriendlyName", &var, 0);
                    }

                    if (SUCCEEDED(hr))
                    {
                        cam.name = var.bstrVal;

                        VariantClear(&var);
                    }

                    hr = pPropBag->Read(L"DevicePath", &var, 0);
                    if (SUCCEEDED(hr))
                    {
                        std::wstring strInfo = var.bstrVal;
                        std::wstring subStr = L"";
                        std::wstring strVid = L"";
                        std::wstring strPid = L"";
                        cam.detail = strInfo;
                        myDebug()<<strInfo;
                        //硬件厂商id Ven 或者vid int
                        size_t nPos = strInfo.find(L"vid_", 0);
                        if(nPos !=  std::wstring::npos)
                        {
                            subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
                            size_t nSubPos = subStr.find(L"&", 0);
                            strVid = subStr.substr(0, nSubPos);
                            cam.vid = strVid;
                        }
                        else
                        {
                            size_t nPos = strInfo.find(L"ven_", 0);
                            if(nPos != std::wstring::npos)
                            {
                                subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
                                size_t nSubPos = subStr.find(L"&", 0);
                                strVid = subStr.substr(0, nSubPos);
                                cam.vid = strVid;
                            }
                            else
                            {
                                size_t nPos = strInfo.find(L"int", 0);
                                if(nPos != std::wstring::npos)
                                {
                                    subStr = strInfo.substr(nPos+3,strInfo.length() - nPos-3);
                                    size_t nSubPos = subStr.find(L"#", 0);
                                    strVid = subStr.substr(0, nSubPos);
                                    cam.vid = strVid;
                                }
                            }
                        }
                        //代表产品编号DEV pid uid
                        nPos = strInfo.find(L"pid_", 0);
                        subStr = L"";
                        if(nPos != std::wstring::npos)
                        {
                            subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
                            size_t nSubPos = subStr.find(L"&", 0);
                            strPid = subStr.substr(0, nSubPos);
                            cam.pid = strPid;
                        }
                        else
                        {
                            nPos = strInfo.find(L"dev_", 0);
                            subStr = L"";
                            if(nPos != std::wstring::npos)
                            {
                                subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
                                size_t nSubPos = subStr.find(L"&", 0);
                                strPid = subStr.substr(0, nSubPos);
                                cam.pid = strPid;
                            }
                            else
                            {
                                nPos = strInfo.find(L"uid", 0);
                                subStr = L"";
                                if(nPos != std::wstring::npos)
                                {
                                    subStr = strInfo.substr(nPos+3,strInfo.length() - nPos-3);
                                    size_t nSubPos = subStr.find(L"#", 0);
                                    strPid = subStr.substr(0, nSubPos);
                                    cam.pid = strPid;
                                }
                            }
                        }


                        VariantClear(&var);
                    }

                    pPropBag->Release();
                    pMoniker->Release();
                    list.push_back(cam);
                    ++deviceCounter;
                }
                pEnum->Release();
            }

            CoUninitialize();
        }

        return deviceCounter;

    }

    int listCameraDevices(std::vector<CameraInfo> &list, QStringList &CameraList, QStringList checkCameraLiist)
    {
        int deviceCounter = 0;
        HRESULT hr = CoInitialize(NULL);
        if (SUCCEEDED(hr))
        {
            IEnumMoniker *pEnum;

            ICreateDevEnum *pDevEnum;
            HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
                CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

            if (SUCCEEDED(hr))
            {
                // Create an enumerator for the category.
                hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
                if (hr == S_FALSE)
                {
                    hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
                }
                pDevEnum->Release();
            }


            if (SUCCEEDED(hr))
            {
                IMoniker *pMoniker = NULL;

                while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
                {
                    IPropertyBag *pPropBag;
                    HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
                    if (FAILED(hr))
                    {
                        pMoniker->Release();
                        continue;
                    }

                    CameraInfo cam;

                    VARIANT var;
                    VariantInit(&var);

                    // Get description or friendly name.
                    hr = pPropBag->Read(L"Description", &var, 0);
                    if (FAILED(hr))
                    {
                        hr = pPropBag->Read(L"FriendlyName", &var, 0);
                    }

                    if (SUCCEEDED(hr))
                    {
                        cam.name = var.bstrVal;
                        QString sCameraName = QString::fromStdWString(cam.name);
                        for(int i = 0; i < checkCameraLiist.count(); ++i)
                        {
                            if(sCameraName.toLower().indexOf(checkCameraLiist[i].toLower()) == 0)
                            {
                                if(CameraList.indexOf(sCameraName) < 0)
                                {
                                    CameraList.push_back(sCameraName);
                                }

                            }
                        }

                        VariantClear(&var);
                    }

                    hr = pPropBag->Read(L"DevicePath", &var, 0);
                    if (SUCCEEDED(hr))
                    {
                        std::wstring strInfo = var.bstrVal;
                        std::wstring subStr = L"";
                        std::wstring strVid = L"";
                        std::wstring strPid = L"";
                        cam.detail = strInfo;
                        myDebug()<<strInfo;
                        //硬件厂商id Ven 或者vid int
                        size_t nPos = strInfo.find(L"vid_", 0);
                        if(nPos !=  std::wstring::npos)
                        {
                            subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
                            size_t nSubPos = subStr.find(L"&", 0);
                            strVid = subStr.substr(0, nSubPos);
                            cam.vid = strVid;
                        }
                        else
                        {
                            size_t nPos = strInfo.find(L"ven_", 0);
                            if(nPos != std::wstring::npos)
                            {
                                subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
                                size_t nSubPos = subStr.find(L"&", 0);
                                strVid = subStr.substr(0, nSubPos);
                                cam.vid = strVid;
                            }
                            else
                            {
                                size_t nPos = strInfo.find(L"int", 0);
                                if(nPos != std::wstring::npos)
                                {
                                    subStr = strInfo.substr(nPos+3,strInfo.length() - nPos-3);
                                    size_t nSubPos = subStr.find(L"#", 0);
                                    strVid = subStr.substr(0, nSubPos);
                                    cam.vid = strVid;
                                }
                            }
                        }
                        //代表产品编号DEV pid uid
                        nPos = strInfo.find(L"pid_", 0);
                        subStr = L"";
                        if(nPos != std::wstring::npos)
                        {
                            subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
                            size_t nSubPos = subStr.find(L"&", 0);
                            strPid = subStr.substr(0, nSubPos);
                            cam.pid = strPid;
                        }
                        else
                        {
                            nPos = strInfo.find(L"dev_", 0);
                            subStr = L"";
                            if(nPos != std::wstring::npos)
                            {
                                subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
                                size_t nSubPos = subStr.find(L"&", 0);
                                strPid = subStr.substr(0, nSubPos);
                                cam.pid = strPid;
                            }
                            else
                            {
                                nPos = strInfo.find(L"uid", 0);
                                subStr = L"";
                                if(nPos != std::wstring::npos)
                                {
                                    subStr = strInfo.substr(nPos+3,strInfo.length() - nPos-3);
                                    size_t nSubPos = subStr.find(L"#", 0);
                                    strPid = subStr.substr(0, nSubPos);
                                    cam.pid = strPid;
                                }
                            }
                        }


                        VariantClear(&var);
                    }

                    pPropBag->Release();
                    pMoniker->Release();
                    list.push_back(cam);
                    ++deviceCounter;
                }
                pEnum->Release();
            }

            CoUninitialize();
        }

        return deviceCounter;





//        ICreateDevEnum *pDevEnum = NULL;
//        IEnumMoniker *pEnum = NULL;
//        int deviceCounter = 0;
//        CoInitialize(NULL);

//        HRESULT hr = CoCreateInstance(
//            CLSID_SystemDeviceEnum,
//            NULL,
//            CLSCTX_INPROC_SERVER,
//            IID_ICreateDevEnum,
//            reinterpret_cast<void**>(&pDevEnum)
//        );

//        if (SUCCEEDED(hr))
//        {
//            hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnum, 0);
//            if (hr == S_OK)
//            {
//    //            int nIdx = 0;
//                IMoniker *pMoniker = NULL;
//                while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
//                {
//                    IPropertyBag *pPropBag;
//                    hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
//                    (void**)(&pPropBag));

//                    if (FAILED(hr)) {
//                          pMoniker->Release();
//                          continue; // Skip this one, maybe the next one will work.

//                    }

//                    VARIANT var;
//                    VariantInit(&var);

//                    hr = pPropBag->Read(L"Description", &var, 0);
//                    if (FAILED(hr))
//                    {
//                        hr = pPropBag->Read(L"FriendlyName", &var, 0);
//                    }

//                    CameraInfo cam;
//                    LPOLESTR pwszName;

//                    pMoniker->GetDisplayName(0,NULL,&pwszName);
//                    std::wstring strInfo = pwszName;
//                     std::wstring subStr = L"";
//                     std::wstring strVid = L"";
//                     std::wstring strPid = L"";
//                    cam.detail = strInfo;
//                    myDebug()<<strInfo;
//                    //硬件厂商id Ven 或者vid int
//                    size_t nPos = strInfo.find(L"vid_", 0);
//                    if(nPos !=  std::wstring::npos)
//                    {
//                        subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
//                        size_t nSubPos = subStr.find(L"&", 0);
//                        strVid = subStr.substr(0, nSubPos);
//                        cam.vid = strVid;
//                    }
//                    else
//                    {
//                        size_t nPos = strInfo.find(L"ven_", 0);
//                        if(nPos != std::wstring::npos)
//                        {
//                            subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
//                            size_t nSubPos = subStr.find(L"&", 0);
//                            strVid = subStr.substr(0, nSubPos);
//                            cam.vid = strVid;
//                        }
//                        else
//                        {
//                            size_t nPos = strInfo.find(L"int", 0);
//                            if(nPos != std::wstring::npos)
//                            {
//                                subStr = strInfo.substr(nPos+3,strInfo.length() - nPos-3);
//                                size_t nSubPos = subStr.find(L"#", 0);
//                                strVid = subStr.substr(0, nSubPos);
//                                cam.vid = strVid;
//                            }
//                        }
//                    }
//                    //代表产品编号DEV pid uid
//                    nPos = strInfo.find(L"pid_", 0);
//                    subStr = L"";
//                    if(nPos != std::wstring::npos)
//                    {
//                        subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
//                        size_t nSubPos = subStr.find(L"&", 0);
//                        strPid = subStr.substr(0, nSubPos);
//                        cam.pid = strPid;
//                    }
//                    else
//                    {
//                        nPos = strInfo.find(L"dev_", 0);
//                        subStr = L"";
//                        if(nPos != std::wstring::npos)
//                        {
//                            subStr = strInfo.substr(nPos+4,strInfo.length() - nPos-4);
//                            size_t nSubPos = subStr.find(L"&", 0);
//                            strPid = subStr.substr(0, nSubPos);
//                            cam.pid = strPid;
//                        }
//                        else
//                        {
//                            nPos = strInfo.find(L"uid", 0);
//                            subStr = L"";
//                            if(nPos != std::wstring::npos)
//                            {
//                                subStr = strInfo.substr(nPos+3,strInfo.length() - nPos-3);
//                                size_t nSubPos = subStr.find(L"#", 0);
//                                strPid = subStr.substr(0, nSubPos);
//                                cam.pid = strPid;
//                            }
//                        }
//                    }


//                    VARIANT varName;
//                    VariantInit(&varName);
//                    hr = pPropBag->Read(L"Description", &varName, 0);
//                    if (FAILED(hr))
//                    {
//                          hr = pPropBag->Read(L"FriendlyName", &varName, 0);

//                    }

//                    if (SUCCEEDED(hr))
//                    {
//                        hr = pPropBag->Read(L"FriendlyName", &varName, 0);
//                        int count = 0;
//                        wchar_t wtmp[255] = { 0 };
//                        char tmp[255] = { 0 };
//                        memset(tmp, 0, 255);
//                        while (varName.bstrVal[count] != 0x00 && count < 255)
//                        {
//                            wtmp[count] = (wchar_t)varName.bstrVal[count];
//                            count++;
//                        }

//                        cam.name = wtmp;
//                        list.push_back(cam);
//                    }

//                    pPropBag->Release();
//                    pPropBag = NULL;
//                    pMoniker->Release();
//                    pMoniker = NULL;

//                    deviceCounter++;
//                }

//                pDevEnum->Release();
//                pDevEnum = NULL;
//                pEnum->Release();
//                pEnum = NULL;
//            }
//        }
//        CoUninitialize();
//        return deviceCounter;
    }

    QString fileMd5(QString sFileName)//获取文件MD5值
    {
        QFile theFile(sFileName);
        if(!theFile.open(QIODevice::ReadOnly))
        {
            return "";
        }
        QByteArray ba = QCryptographicHash::hash(theFile.readAll(), QCryptographicHash::Md5);
        theFile.close();
        return ba.toHex().constData();

    }

    void topMostSlot(QWidget *widget, bool bTopMost)
    {
        if(bTopMost)
        {
            Qt::WindowFlags m_flags = widget->windowFlags();
            widget->setWindowFlags(m_flags | Qt::WindowStaysOnTopHint);
            widget->show();
        }
        else
        {
            Qt::WindowFlags m_flags = Qt::FramelessWindowHint;
            widget->setWindowFlags(m_flags);
            widget->show();
        }
    }

    QImage Mat2QImage(const cv::Mat& mat)
    {
        try
        {
            //8-bitsunsigned,NO.OFCHANNELS=1
            if(mat.type()==CV_8UC1)
            {
                QVector<QRgb>colorTable;
                for(int i=0;i<256;i++)
                {
                    colorTable.push_back(qRgb(i,i,i));
                }
                const uchar*qImageBuffer=(const uchar*)mat.data;

                QImage img(qImageBuffer,mat.cols,mat.rows,mat.step,QImage::Format_Indexed8);
                img.setColorTable(colorTable);
                return img;
            }
            //8-bitsunsigned,NO.OFCHANNELS=3
            if(mat.type()==CV_8UC3)
            {
                //CopyinputMat
                const uchar* qImageBuffer = (const uchar*)mat.data;

                QImage img(qImageBuffer,mat.cols,mat.rows,mat.step,QImage::Format_RGB888);
                return img.rgbSwapped();

            }
            else if(mat.type()==CV_8UC4)
            {
                const uchar* qImageBuffer = (const uchar*)mat.data;

                QImage img(qImageBuffer,mat.cols,mat.rows,mat.step,QImage::Format_RGBA8888);
                return img.rgbSwapped();

            }
            else
            {
                myDebug()<<"Mat to Image error";
                return QImage();
            }
        }
        catch(std::exception &e)
        {
            myDebug()<<"Mat2QImage"<<e.what();
            return QImage();
        }
    }

    bool checkMat(cv::Mat& mat)
    {
        for (int i = 0; i < mat.rows; i++)
        {
            uchar* pRow = (unsigned char*)mat.ptr<uchar>(i);
            for (int j = 0; j < mat.cols * mat.channels(); j++)
            {
            #ifdef _DEBUG
                if (pRow[j] != 0xcd)
            #else
                if (pRow[j])
            #endif
                {
                    return true;
                }
            }
        }
        return false;
    }

    void genRandomNumber(QList<int> &listRandom, int nSize)
    {
        for(int i = 1; i <= nSize; i++)
        {
            listRandom.push_back(i);
        }

        std::random_device rd;
        std::mt19937 g(rd());
        std::shuffle(listRandom.begin(), listRandom.end(), g);
    }

    int genRandomNumber(int nForm, int nTo)
    {
        std::random_device rand_dev;
        std::mt19937 generator(rand_dev());
        std::uniform_int_distribution<int>  distr(nForm, nTo);
        return distr(generator);
    }

    QString getImageRawBase64Str(QString sBase64Image)
    {
        int nIndex = sBase64Image.indexOf("base64,");
        if(nIndex >= 0)
        {
            return sBase64Image.right(sBase64Image.length() - nIndex - 7);
        }
        return sBase64Image;
    }
}
