diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml
index 28205f001..ebe3bdc1c 100644
--- a/PowerEditor/installer/nativeLang/english.xml
+++ b/PowerEditor/installer/nativeLang/english.xml
@@ -76,6 +76,7 @@ Translation note:
+
@@ -545,6 +546,29 @@ Translation note:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PowerEditor/installer/nativeLang/english_customizable.xml b/PowerEditor/installer/nativeLang/english_customizable.xml
index 6b69b3c28..b953f63ac 100644
--- a/PowerEditor/installer/nativeLang/english_customizable.xml
+++ b/PowerEditor/installer/nativeLang/english_customizable.xml
@@ -76,6 +76,7 @@ Translation note:
+
@@ -545,6 +546,30 @@ Translation note:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PowerEditor/installer/nativeLang/french.xml b/PowerEditor/installer/nativeLang/french.xml
index 8e73923b8..5e46684fe 100644
--- a/PowerEditor/installer/nativeLang/french.xml
+++ b/PowerEditor/installer/nativeLang/french.xml
@@ -542,6 +542,30 @@ The comments are here for explanation, it's not necessary to translate them.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PowerEditor/installer/nativeLang/taiwaneseMandarin.xml b/PowerEditor/installer/nativeLang/taiwaneseMandarin.xml
index 5aa78ca9b..66dc65151 100644
--- a/PowerEditor/installer/nativeLang/taiwaneseMandarin.xml
+++ b/PowerEditor/installer/nativeLang/taiwaneseMandarin.xml
@@ -518,6 +518,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PowerEditor/src/MISC/md5/md5Dlgs.cpp b/PowerEditor/src/MISC/md5/md5Dlgs.cpp
index 0eea478bb..555ffd148 100644
--- a/PowerEditor/src/MISC/md5/md5Dlgs.cpp
+++ b/PowerEditor/src/MISC/md5/md5Dlgs.cpp
@@ -17,6 +17,7 @@
#include "md5.h"
#include
#include "sha-256.h"
+#include "sha512.h"
#include "calc_sha1.h"
#include "md5Dlgs.h"
#include "md5Dlgs_rc.h"
@@ -132,23 +133,35 @@ intptr_t CALLBACK HashFromFilesDlg::run_dlgProc(UINT message, WPARAM wParam, LPA
{
std::string content = getFileContent(it.c_str());
- bool isSha256 = (_ht == hashType::hash_sha256);
+ uint8_t hash[HASH_MAX_LENGTH]{};
+ wchar_t hashStr[HASH_STR_MAX_LENGTH]{};
- uint8_t hash[32]{}; // align to the longest hash (SHA-256)
- wchar_t hashStr[65]{}; // align to the longest hash (SHA-256)
- size_t hashLen = 0;
- if (isSha256)
+ switch (_ht)
{
- calc_sha_256(hash, reinterpret_cast(content.c_str()), content.length());
- hashLen = 32;
- }
- else
- {
- calc_sha1(hash, reinterpret_cast(content.c_str()), content.length());
- hashLen = 20;
+ case hash_sha1:
+ {
+ calc_sha1(hash, reinterpret_cast(content.c_str()), content.length());
+ }
+ break;
+
+ case hash_sha256:
+ {
+ calc_sha_256(hash, reinterpret_cast(content.c_str()), content.length());
+ }
+ break;
+
+ case hash_sha512:
+ {
+ calc_sha_512(hash, reinterpret_cast(content.c_str()), content.length());
+ }
+ break;
+
+ default:
+ return FALSE;
+
}
- for (size_t i = 0; i < hashLen; i++)
+ for (int i = 0; i < _ht; i++)
wsprintf(hashStr + i * 2, TEXT("%02x"), hash[i]);
files2check += it;
@@ -227,23 +240,37 @@ void HashFromFilesDlg::doDialog(bool isRTL)
if (!isCreated())
{
create(IDD_HASHFROMFILES_DLG, isRTL);
+ std::wstring title;
+ std::wstring buttonText;
- if (_ht == hash_sha256)
+ switch (_ht)
{
- generic_string title = TEXT("Generate SHA-256 digest from files");
- ::SetWindowText(_hSelf, title.c_str());
+ case hash_sha1:
+ {
+ title = TEXT("Generate SHA-1 digest from files");
+ buttonText = TEXT("Choose files to &generate SHA-1...");
+ }
+ break;
- generic_string buttonText = TEXT("Choose files to &generate SHA-256...");
- ::SetDlgItemText(_hSelf, IDC_HASH_FILEBROWSER_BUTTON, buttonText.c_str());
- }
- else if (_ht == hash_sha1)
- {
- generic_string title = TEXT("Generate SHA-1 digest from files");
- ::SetWindowText(_hSelf, title.c_str());
+ case hash_sha256:
+ {
+ title = TEXT("Generate SHA-256 digest from files");
+ buttonText = TEXT("Choose files to &generate SHA-256...");
+ }
+ break;
- generic_string buttonText = TEXT("Choose files to &generate SHA-1...");
- ::SetDlgItemText(_hSelf, IDC_HASH_FILEBROWSER_BUTTON, buttonText.c_str());
+ case hash_sha512:
+ {
+ title = TEXT("Generate SHA-1 digest from files");
+ buttonText = TEXT("Choose files to &generate SHA-512...");
+ }
+ break;
+
+ default:
+ return;
}
+ ::SetWindowText(_hSelf, title.c_str());
+ ::SetDlgItemText(_hSelf, IDC_HASH_FILEBROWSER_BUTTON, buttonText.c_str());
}
// Adjust the position in the center
@@ -252,7 +279,7 @@ void HashFromFilesDlg::doDialog(bool isRTL)
void HashFromTextDlg::generateHash()
{
- if (_ht != hash_md5 && _ht != hash_sha256 && _ht != hash_sha1)
+ if (_ht != hash_md5 && _ht != hash_sha1 && _ht != hash_sha256 && _ht != hash_sha512)
return;
int len = static_cast(::SendMessage(::GetDlgItem(_hSelf, IDC_HASH_TEXT_EDIT), WM_GETTEXTLENGTH, 0, 0));
@@ -272,23 +299,34 @@ void HashFromTextDlg::generateHash()
}
else
{
- uint8_t hash[32]{}; // align to the longest hash (SHA-256)
- wchar_t hashStr[65]{}; // align to the longest hash (SHA-256)
- size_t hashLen = 0;
- bool isSha256 = (_ht == hash_sha256);
+ uint8_t hash[HASH_MAX_LENGTH]{};
+ wchar_t hashStr[HASH_STR_MAX_LENGTH]{};
- if (isSha256)
+ switch (_ht)
{
- calc_sha_256(hash, reinterpret_cast(newText), strlen(newText));
- hashLen = 32;
- }
- else
- {
- calc_sha1(hash, reinterpret_cast(newText), strlen(newText));
- hashLen = 20;
+ case hash_sha1:
+ {
+ calc_sha1(hash, reinterpret_cast(newText), strlen(newText));
+ }
+ break;
+
+ case hash_sha256:
+ {
+ calc_sha_256(hash, reinterpret_cast(newText), strlen(newText));
+ }
+ break;
+
+ case hash_sha512:
+ {
+ calc_sha_512(hash, reinterpret_cast(newText), strlen(newText));
+ }
+ break;
+
+ default:
+ return;
}
- for (size_t i = 0; i < hashLen; i++)
+ for (int i = 0; i < _ht; i++)
wsprintf(hashStr + i * 2, TEXT("%02x"), hash[i]);
::SetDlgItemText(_hSelf, IDC_HASH_RESULT_FOMTEXT_EDIT, hashStr);
@@ -312,54 +350,78 @@ void HashFromTextDlg::generateHashPerLine()
std::wstringstream ss(text);
std::wstring aLine;
std::string result;
- MD5 md5;
+
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
+
while (std::getline(ss, aLine))
{
- // getline() detect only '\n' but not "\r\n" under windows
- // this hack is to walk around such bug
- if (aLine.back() == '\r')
- aLine = aLine.substr(0, aLine.size() - 1);
-
- if (aLine.empty())
+ if (aLine.empty()) // in case of UNIX EOL
+ {
result += "\r\n";
+ }
else
{
- const char *newText = wmc.wchar2char(aLine.c_str(), SC_CP_UTF8);
+ // getline() detect only '\n' but not "\r\n" under Windows
+ // this hack is to walk around such bug
+ if (aLine.back() == '\r')
+ aLine = aLine.substr(0, aLine.size() - 1);
- if (_ht == hash_md5)
+ if (aLine.empty()) // Windows EOL, both \n & \r are removed
{
- char* md5Result = md5.digestString(newText);
- result += md5Result;
result += "\r\n";
}
else
{
- uint8_t hash[32]{}; // align to the longest hash (SHA-256)
- char hashStr[65]{}; // align to the longest hash (SHA-256)
- size_t hashLen = 0;
- bool isSha256 = (_ht == hash_sha256);
+ const char* newText = wmc.wchar2char(aLine.c_str(), SC_CP_UTF8);
- if (isSha256)
+ if (_ht == hash_md5)
{
- calc_sha_256(hash, reinterpret_cast(newText), strlen(newText));
- hashLen = 32;
+ MD5 md5;
+ char* md5Result = md5.digestString(newText);
+ result += md5Result;
+ result += "\r\n";
}
else
{
- calc_sha1(hash, reinterpret_cast(newText), strlen(newText));
- hashLen = 20;
- }
-
- for (size_t i = 0; i < 32; i++)
- sprintf(hashStr + i * 2, "%02x", hash[i]);
+ uint8_t hash[HASH_MAX_LENGTH]{};
+ char hashStr[HASH_STR_MAX_LENGTH]{};
- result += hashStr;
- result += "\r\n";
+ switch (_ht)
+ {
+ case hash_sha1:
+ {
+ calc_sha1(hash, reinterpret_cast(newText), strlen(newText));
+ }
+ break;
+
+ case hash_sha256:
+ {
+ calc_sha_256(hash, reinterpret_cast(newText), strlen(newText));
+ }
+ break;
+
+ case hash_sha512:
+ {
+ calc_sha_512(hash, reinterpret_cast(newText), strlen(newText));
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ for (int i = 0; i < _ht; i++)
+ sprintf(hashStr + i * 2, "%02x", hash[i]);
+
+ result += hashStr;
+ result += "\r\n";
+ }
}
}
}
+
delete[] text;
+
::SetDlgItemTextA(_hSelf, IDC_HASH_RESULT_FOMTEXT_EDIT, result.c_str());
}
else
@@ -501,17 +563,32 @@ void HashFromTextDlg::doDialog(bool isRTL)
if (!isCreated())
{
create(IDD_HASHFROMTEXT_DLG, isRTL);
+ std::wstring title;
+ switch (_ht)
+ {
+ case hash_sha1:
+ {
+ title = TEXT("Generate SHA-1 digest");
+ }
+ break;
- if (_ht == hash_sha256)
- {
- generic_string title = TEXT("Generate SHA-256 digest");
- ::SetWindowText(_hSelf, title.c_str());
- }
- else if (_ht == hash_sha1)
- {
- generic_string title = TEXT("Generate SHA-1 digest");
- ::SetWindowText(_hSelf, title.c_str());
+ case hash_sha256:
+ {
+ title = TEXT("Generate SHA-256 digest");
+ }
+ break;
+
+ case hash_sha512:
+ {
+ title = TEXT("Generate SHA-512 digest");
+ }
+ break;
+
+ default:
+ break;
}
+
+ ::SetWindowText(_hSelf, title.c_str());
}
// Adjust the position in the center
diff --git a/PowerEditor/src/MISC/md5/md5Dlgs.h b/PowerEditor/src/MISC/md5/md5Dlgs.h
index 446ce2d93..9ba204c0b 100644
--- a/PowerEditor/src/MISC/md5/md5Dlgs.h
+++ b/PowerEditor/src/MISC/md5/md5Dlgs.h
@@ -18,7 +18,10 @@
#include "StaticDialog.h"
-enum hashType {hash_md5, hash_sha256, hash_sha1};
+enum hashType {hash_md5 = 16, hash_sha1 = 20, hash_sha256 = 32, hash_sha512 = 64};
+
+#define HASH_MAX_LENGTH hash_sha512
+#define HASH_STR_MAX_LENGTH (hash_sha512 * 2 + 1)
LRESULT run_textEditProc(WNDPROC oldEditProc, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
diff --git a/PowerEditor/src/MISC/sha512/sha512.cpp b/PowerEditor/src/MISC/sha512/sha512.cpp
new file mode 100644
index 000000000..c280171d2
--- /dev/null
+++ b/PowerEditor/src/MISC/sha512/sha512.cpp
@@ -0,0 +1,56 @@
+// This file is part of Notepad++ project
+// Copyright (C)2023 Don HO
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+#include
+#include "sha512.h"
+
+#pragma comment(lib, "crypt32.lib")
+
+void calc_sha_512(unsigned char hash[64], const void *input, size_t len) {
+ HCRYPTPROV hProv = 0;
+ HCRYPTHASH hHash = 0;
+ DWORD dwHashLen = 64;
+
+ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
+ //std::cerr << "CryptAcquireContext failed: " << GetLastError() << std::endl;
+ return;
+ }
+
+ if (!CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash)) {
+ //std::cerr << "CryptCreateHash failed: " << GetLastError() << std::endl;
+ CryptReleaseContext(hProv, 0);
+ return;
+ }
+
+ if (!CryptHashData(hHash, (BYTE*)input, DWORD(len), 0)) {
+ //std::cerr << "CryptHashData failed: " << GetLastError() << std::endl;
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+ return;
+ }
+
+ if (!CryptGetHashParam(hHash, HP_HASHVAL, hash, &dwHashLen, 0)) {
+ //std::cerr << "CryptGetHashParam failed: " << GetLastError() << std::endl;
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+ return;
+ }
+
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+}
+
diff --git a/PowerEditor/src/MISC/sha512/sha512.h b/PowerEditor/src/MISC/sha512/sha512.h
new file mode 100644
index 000000000..17fea6dff
--- /dev/null
+++ b/PowerEditor/src/MISC/sha512/sha512.h
@@ -0,0 +1,19 @@
+// This file is part of Notepad++ project
+// Copyright (C)2023 Don HO
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#pragma once
+
+void calc_sha_512(unsigned char hash[64], const void *input, size_t len);
diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp
index 54233bc45..1527c78d2 100644
--- a/PowerEditor/src/Notepad_plus.cpp
+++ b/PowerEditor/src/Notepad_plus.cpp
@@ -717,6 +717,10 @@ LRESULT Notepad_plus::init(HWND hwnd)
_sha1FromFilesDlg.setHashType(hash_sha1);
_sha1FromTextDlg.init(_pPublicInterface->getHinst(), hwnd);
_sha1FromTextDlg.setHashType(hash_sha1);
+ _sha512FromFilesDlg.init(_pPublicInterface->getHinst(), hwnd);
+ _sha512FromFilesDlg.setHashType(hash_sha512);
+ _sha512FromTextDlg.init(_pPublicInterface->getHinst(), hwnd);
+ _sha512FromTextDlg.setHashType(hash_sha512);
//--User Define Dialog Section--//
diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h
index 3796bcd4e..58f4ebac3 100644
--- a/PowerEditor/src/Notepad_plus.h
+++ b/PowerEditor/src/Notepad_plus.h
@@ -316,6 +316,8 @@ private:
HashFromTextDlg _sha2FromTextDlg;
HashFromFilesDlg _sha1FromFilesDlg;
HashFromTextDlg _sha1FromTextDlg;
+ HashFromFilesDlg _sha512FromFilesDlg;
+ HashFromTextDlg _sha512FromTextDlg;
GoToLineDlg _goToLineDlg;
ColumnEditorDlg _colEditorDlg;
WordStyleDlg _configStyleDlg;
diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc
index 31ecf5a94..c45baded0 100644
--- a/PowerEditor/src/Notepad_plus.rc
+++ b/PowerEditor/src/Notepad_plus.rc
@@ -1185,6 +1185,12 @@ BEGIN
MENUITEM "Generate from files...", IDM_TOOL_SHA256_GENERATEFROMFILE
MENUITEM "Generate from selection into clipboard", IDM_TOOL_SHA256_GENERATEINTOCLIPBOARD
END
+ POPUP "SHA-512"
+ BEGIN
+ MENUITEM "Generate...", IDM_TOOL_SHA512_GENERATE
+ MENUITEM "Generate from files...", IDM_TOOL_SHA512_GENERATEFROMFILE
+ MENUITEM "Generate from selection into clipboard", IDM_TOOL_SHA512_GENERATEINTOCLIPBOARD
+ END
END
POPUP "&Macro"
diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp
index 8564e2402..e9f3acb85 100644
--- a/PowerEditor/src/NppCommands.cpp
+++ b/PowerEditor/src/NppCommands.cpp
@@ -34,6 +34,7 @@
#include "md5.h"
#include "sha-256.h"
#include "calc_sha1.h"
+#include "sha512.h"
using namespace std;
@@ -3214,24 +3215,6 @@ void Notepad_plus::command(int id)
}
break;
- case IDM_TOOL_SHA256_GENERATE:
- {
- bool isFirstTime = !_sha2FromTextDlg.isCreated();
- _sha2FromTextDlg.doDialog(_nativeLangSpeaker.isRTL());
- if (isFirstTime)
- _nativeLangSpeaker.changeDlgLang(_sha2FromTextDlg.getHSelf(), "SHA256FromTextDlg");
- }
- break;
-
- case IDM_TOOL_SHA256_GENERATEFROMFILE:
- {
- bool isFirstTime = !_sha2FromFilesDlg.isCreated();
- _sha2FromFilesDlg.doDialog(_nativeLangSpeaker.isRTL());
- if (isFirstTime)
- _nativeLangSpeaker.changeDlgLang(_sha2FromFilesDlg.getHSelf(), "SHA256FromFilesDlg");
- }
- break;
-
case IDM_TOOL_SHA1_GENERATE:
{
bool isFirstTime = !_sha1FromTextDlg.isCreated();
@@ -3250,8 +3233,45 @@ void Notepad_plus::command(int id)
}
break;
- case IDM_TOOL_SHA256_GENERATEINTOCLIPBOARD:
+ case IDM_TOOL_SHA256_GENERATE:
+ {
+ bool isFirstTime = !_sha2FromTextDlg.isCreated();
+ _sha2FromTextDlg.doDialog(_nativeLangSpeaker.isRTL());
+ if (isFirstTime)
+ _nativeLangSpeaker.changeDlgLang(_sha2FromTextDlg.getHSelf(), "SHA256FromTextDlg");
+ }
+ break;
+
+ case IDM_TOOL_SHA256_GENERATEFROMFILE:
+ {
+ bool isFirstTime = !_sha2FromFilesDlg.isCreated();
+ _sha2FromFilesDlg.doDialog(_nativeLangSpeaker.isRTL());
+ if (isFirstTime)
+ _nativeLangSpeaker.changeDlgLang(_sha2FromFilesDlg.getHSelf(), "SHA256FromFilesDlg");
+ }
+ break;
+
+ case IDM_TOOL_SHA512_GENERATE:
+ {
+ bool isFirstTime = !_sha512FromTextDlg.isCreated();
+ _sha512FromTextDlg.doDialog(_nativeLangSpeaker.isRTL());
+ if (isFirstTime)
+ _nativeLangSpeaker.changeDlgLang(_sha512FromTextDlg.getHSelf(), "SHA512FromTextDlg");
+ }
+ break;
+
+ case IDM_TOOL_SHA512_GENERATEFROMFILE:
+ {
+ bool isFirstTime = !_sha512FromFilesDlg.isCreated();
+ _sha512FromFilesDlg.doDialog(_nativeLangSpeaker.isRTL());
+ if (isFirstTime)
+ _nativeLangSpeaker.changeDlgLang(_sha512FromFilesDlg.getHSelf(), "SHA512FromFilesDlg");
+ }
+ break;
+
case IDM_TOOL_SHA1_GENERATEINTOCLIPBOARD:
+ case IDM_TOOL_SHA256_GENERATEINTOCLIPBOARD:
+ case IDM_TOOL_SHA512_GENERATEINTOCLIPBOARD:
{
if (_pEditView->execute(SCI_GETSELECTIONS) == 1)
{
@@ -3265,23 +3285,33 @@ void Notepad_plus::command(int id)
char *selectedStr = new char[strSize];
_pEditView->execute(SCI_GETSELTEXT, 0, reinterpret_cast(selectedStr));
- bool isSha256 = (id == IDM_TOOL_SHA256_GENERATEINTOCLIPBOARD);
+ uint8_t hash[HASH_MAX_LENGTH] {};
+ wchar_t hashStr[HASH_STR_MAX_LENGTH] {};
- uint8_t hash[32] {}; // align to the longest hash (SHA-256)
- wchar_t hashStr[65] {}; // align to the longest hash (SHA-256)
- size_t hashLen = 0;
- if (isSha256)
+ switch (id)
{
- calc_sha_256(hash, reinterpret_cast(selectedStr), strlen(selectedStr));
- hashLen = 32;
+ case IDM_TOOL_SHA1_GENERATEINTOCLIPBOARD:
+ {
+ calc_sha1(hash, reinterpret_cast(selectedStr), strlen(selectedStr));
+ }
+ break;
+
+ case IDM_TOOL_SHA256_GENERATEINTOCLIPBOARD:
+ {
+ calc_sha_256(hash, reinterpret_cast(selectedStr), strlen(selectedStr));
+ }
+ break;
+
+ case IDM_TOOL_SHA512_GENERATEINTOCLIPBOARD:
+ {
+ calc_sha_512(hash, reinterpret_cast(selectedStr), strlen(selectedStr));
+ }
+ break;
+
+ default:
+ return;
}
- else // SHA1
- {
- calc_sha1(hash, reinterpret_cast(selectedStr), strlen(selectedStr));
- hashLen = 20;
- }
-
- for (size_t i = 0; i < hashLen; i++)
+ for (int i = 0; i < id; i++)
wsprintf(hashStr + i * 2, TEXT("%02x"), hash[i]);
str2Clipboard(hashStr, _pPublicInterface->getHSelf());
diff --git a/PowerEditor/src/localization.cpp b/PowerEditor/src/localization.cpp
index 080bb34ea..f8868d46e 100644
--- a/PowerEditor/src/localization.cpp
+++ b/PowerEditor/src/localization.cpp
@@ -100,6 +100,7 @@ MenuPosition menuPos[] = {
{ 7, 0, -1, "tools-md5" },
{ 7, 1, -1, "tools-sha1" },
{ 7, 2, -1, "tools-sha256" },
+ { 7, 3, -1, "tools-sha512" },
{ 11, 0, -1, "window-sortby"},
diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h
index cde8825e4..fb10ff681 100644
--- a/PowerEditor/src/menuCmdID.h
+++ b/PowerEditor/src/menuCmdID.h
@@ -596,6 +596,9 @@
#define IDM_TOOL_SHA1_GENERATE (IDM_TOOL + 7)
#define IDM_TOOL_SHA1_GENERATEFROMFILE (IDM_TOOL + 8)
#define IDM_TOOL_SHA1_GENERATEINTOCLIPBOARD (IDM_TOOL + 9)
+ #define IDM_TOOL_SHA512_GENERATE (IDM_TOOL + 10)
+ #define IDM_TOOL_SHA512_GENERATEFROMFILE (IDM_TOOL + 11)
+ #define IDM_TOOL_SHA512_GENERATEINTOCLIPBOARD (IDM_TOOL + 12)
#define IDM_EXECUTE (IDM + 9000)
diff --git a/PowerEditor/visual.net/notepadPlus.Cpp.props b/PowerEditor/visual.net/notepadPlus.Cpp.props
index 75ccff999..aa4440263 100644
--- a/PowerEditor/visual.net/notepadPlus.Cpp.props
+++ b/PowerEditor/visual.net/notepadPlus.Cpp.props
@@ -24,7 +24,7 @@
- ..\src;..\src\MISC;..\src\MISC\Common;..\src\MISC\Exception;..\src\MISC\PluginsManager;..\src\MISC\Process;..\src\MISC\RegExt;..\src\MISC\md5;..\src\MISC\sha1;..\src\MISC\sha2;..\src\MISC\SysMsg;..\src\ScintillaComponent;..\src\Win32Explr;..\src\WinControls;..\src\WinControls\AboutDlg;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\ColourPicker;..\src\WinControls\ContextMenu;..\src\WinControls\DockingWnd;..\src\WinControls\DocumentMap;..\src\WinControls\FileBrowser;..\src\WinControls\FindCharsInRange;..\src\WinControls\FunctionList;..\src\WinControls\Grid;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\PluginsAdmin;..\src\WinControls\Preference;..\src\WinControls\ProjectPanel;..\src\WinControls\ReadDirectoryChanges;..\src\WinControls\shortcut;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\StaticDialog\RunDlg;..\src\WinControls\StatusBar;..\src\WinControls\TabBar;..\src\WinControls\TaskList;..\src\WinControls\ToolBar;..\src\WinControls\ToolTip;..\src\WinControls\TrayIcon;..\src\WinControls\TreeView;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\WindowsDlg;%(AdditionalIncludeDirectories)
+ ..\src;..\src\MISC;..\src\MISC\Common;..\src\MISC\Exception;..\src\MISC\PluginsManager;..\src\MISC\Process;..\src\MISC\RegExt;..\src\MISC\md5;..\src\MISC\sha1;..\src\MISC\sha2;..\src\MISC\sha512;..\src\MISC\SysMsg;..\src\ScintillaComponent;..\src\Win32Explr;..\src\WinControls;..\src\WinControls\AboutDlg;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\ColourPicker;..\src\WinControls\ContextMenu;..\src\WinControls\DockingWnd;..\src\WinControls\DocumentMap;..\src\WinControls\FileBrowser;..\src\WinControls\FindCharsInRange;..\src\WinControls\FunctionList;..\src\WinControls\Grid;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\PluginsAdmin;..\src\WinControls\Preference;..\src\WinControls\ProjectPanel;..\src\WinControls\ReadDirectoryChanges;..\src\WinControls\shortcut;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\StaticDialog\RunDlg;..\src\WinControls\StatusBar;..\src\WinControls\TabBar;..\src\WinControls\TaskList;..\src\WinControls\ToolBar;..\src\WinControls\ToolTip;..\src\WinControls\TrayIcon;..\src\WinControls\TreeView;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\WindowsDlg;%(AdditionalIncludeDirectories)
WIN32;_WIN32_WINNT=_WIN32_WINNT_VISTA;_WINDOWS;OEMRESOURCE;NOMINMAX;_USE_64BIT_TIME_T;TIXML_USE_STL;TIXMLA_USE_STL;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions)
Async
Level4
diff --git a/PowerEditor/visual.net/notepadPlus.vcxproj b/PowerEditor/visual.net/notepadPlus.vcxproj
index 04f47b798..97517da0b 100755
--- a/PowerEditor/visual.net/notepadPlus.vcxproj
+++ b/PowerEditor/visual.net/notepadPlus.vcxproj
@@ -112,6 +112,7 @@
+
@@ -251,6 +252,7 @@
+