2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2021 - Stéphane MOTTELET
5 * This file is hereby licensed under the terms of the GNU GPL v3.0,
6 * For more information, see the COPYING file which you should have received
7 * along with this program.
12 #include "core_gw.hxx"
14 #include "function.hxx"
18 #include "filemanager.hxx"
28 #include "sci_malloc.h"
31 types::Function::ReturnValue sci_hash(types::typed_list &in, int _iRetCount, types::typed_list &out)
33 bool bStringMode = false;
34 char* pstInput = NULL;
36 types::String* pIn = NULL;
37 types::String* pOutput = NULL;
38 types::Double* pDbl = NULL;
43 Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "hash", 1);
44 return types::Function::Error;
49 Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "hash", 2);
50 return types::Function::Error;
53 if (in[0]->isString() == false && in[0]->isDouble() == false)
55 Scierror(999, _("%s: Wrong type of input argument #%d: String or File descriptor expected.\n"), "hash", 1);
56 return types::Function::Error;
59 if (in[1]->isString() == false || in[1]->getAs<types::String>()->isScalar() == false)
61 Scierror(999, _("%s: Wrong type of input argument #%d: a single string expected.\n"), "hash", 2);
62 return types::Function::Error;
65 std::wstring wstrAlgo(in[1]->getAs<types::String>()->get()[0]);
66 std::transform(wstrAlgo.begin(), wstrAlgo.end(), wstrAlgo.begin(),std::towlower);
68 if (wstrAlgo == L"crc32")
72 else if (wstrAlgo == L"md5")
76 else if (wstrAlgo == L"sha1")
80 else if (wstrAlgo == L"sha2" || wstrAlgo == L"sha256")
82 digest = new SHA256();
84 else if (wstrAlgo == L"sha3-224")
86 digest = new SHA3(SHA3::Bits224);
88 else if (wstrAlgo == L"sha3-256")
90 digest = new SHA3(SHA3::Bits256);
92 else if (wstrAlgo == L"sha3-384")
94 digest = new SHA3(SHA3::Bits384);
96 else if (wstrAlgo == L"sha3-512")
98 digest = new SHA3(SHA3::Bits512);
102 Scierror(999, _("%s: algorithm %ls is unknown.\n"), "hash", wstrAlgo.c_str());
103 return types::Function::Error;
106 if (in[0]->isString())
108 pIn = in[0]->getAs<types::String>();
109 pOutput = new types::String(pIn->getRows(), pIn->getCols());
111 iSize = pIn->getSize();
115 pDbl = in[0]->getAs<types::Double>();
116 pOutput = new types::String(pDbl->getRows(), pDbl->getCols());
117 iSize = pDbl->getSize();
120 for (int i = 0; i < iSize; ++i)
122 wchar_t *pwstHash = NULL;
126 wchar_t *pwstInput = pIn->get(i);
127 pstInput = wide_string_to_UTF8(pwstInput);
128 digest->add(pstInput, strlen(pstInput));
136 int iFile = (int) pDbl->get(i);
137 types::File* pF = NULL;
146 pF = FileManager::getFile(iFile);
151 Scierror(999, _("%s: Wrong file descriptor: %d.\n"), "hash", iFile);
152 return types::Function::Error;
154 else if (pF->getFileMode()[0] != L'r')
156 Scierror(999, _("%s: File must be opened for reading.\n"), "hash", iFile);
157 fclose(pF->getFiledesc());
158 FileManager::deleteFile(iFile);
159 return types::Function::Error;
162 fp = pF->getFiledesc();
163 if (fp) // argument is a valid path to an existing file
167 iLen = fread(pStData, 1, sizeof(pStData), fp);
168 digest->add(pStData, iLen);
171 // after closing, don't forget to remove file from the list of opened files
172 //FileManager::deleteFile(iFile);
176 std::string strHash = digest->getHash();
177 if (strHash.length() > 0)
179 pwstHash = to_wide_string(strHash.c_str());
180 pOutput->set(i, pwstHash);
185 pOutput->set(i, L"");
192 out.push_back(pOutput);
193 return types::Function::OK;
195 /*--------------------------------------------------------------------------*/