From 1ff6ba0042c5121b5899c8e42ead7a20c7a13c56 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Fri, 8 Jan 2021 08:56:05 +0100 Subject: [PATCH] Continued: - moved self::$hashLength, getHashLength() and hash() methods to new CryptoUtils class for lesser monolithic code in BaseFrameworkSystem class MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Roland Häder --- .../classes/class_BaseFrameworkSystem.php | 37 -------- .../binary/index/class_IndexFile.php | 7 +- .../binary/stack/class_StackFile.php | 3 +- .../index/file/class_BaseFileIndex.php | 14 +-- .../index/file/stack/class_FileStackIndex.php | 15 +-- .../stacker/file/class_BaseFileStack.php | 3 +- .../utils/crypto/class_CryptoUtils.php | 93 +++++++++++++++++++ 7 files changed, 118 insertions(+), 54 deletions(-) create mode 100644 framework/main/classes/utils/crypto/class_CryptoUtils.php diff --git a/framework/main/classes/class_BaseFrameworkSystem.php b/framework/main/classes/class_BaseFrameworkSystem.php index adda64f4..c0728aae 100644 --- a/framework/main/classes/class_BaseFrameworkSystem.php +++ b/framework/main/classes/class_BaseFrameworkSystem.php @@ -51,11 +51,6 @@ use \SplFileInfo; * along with this program. If not, see . */ abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterface { - /** - * Length of output from hash() - */ - private static $hashLength = NULL; - /** * Self-referencing instance */ @@ -1013,38 +1008,6 @@ Loaded includes: return $executionTime; } - /** - * Hashes a given string with a simple but stronger hash function (no salt) - * and hex-encode it. - * - * @param $str The string to be hashed - * @return $hash The hash from string $str - */ - public static final function hash (string $str) { - // Hash given string with (better secure) hasher - $hash = bin2hex(mhash(MHASH_SHA256, $str)); - - // Return it - return $hash; - } - - /** - * "Getter" for length of hash() output. This will be "cached" to speed up - * things. - * - * @return $length Length of hash() output - */ - public static final function getHashLength () { - // Is it cashed? - if (is_null(self::$hashLength)) { - // No, then hash a string and save its length. - self::$hashLength = strlen(self::hash('abc123')); - } - - // Return it - return self::$hashLength; - } - /** * Determines if an element is set in the generic array * diff --git a/framework/main/classes/file_directories/binary/index/class_IndexFile.php b/framework/main/classes/file_directories/binary/index/class_IndexFile.php index 65044b20..3de99584 100644 --- a/framework/main/classes/file_directories/binary/index/class_IndexFile.php +++ b/framework/main/classes/file_directories/binary/index/class_IndexFile.php @@ -8,6 +8,7 @@ use Org\Mxchange\CoreFramework\Filesystem\File\BaseBinaryFile; use Org\Mxchange\CoreFramework\Filesystem\Index\IndexableFile; use Org\Mxchange\CoreFramework\Generic\UnsupportedOperationException; use Org\Mxchange\CoreFramework\Index\Indexable; +use Org\Mxchange\CoreFramework\Utils\Crypto\CryptoUtils; // Import SPL stuff use \BadMethodCallException; @@ -166,6 +167,7 @@ class IndexFile extends BaseBinaryFile implements IndexableFile { * @param $value Value to be added to the stack * @return $data Hash and gap position * @throws InvalidArgumentException If a parameter is not valid + * @throws BadMethodCallException If this->indexInstance is not properly set */ public function writeValueToFile (string $stackName, $value) { // Validate parameter @@ -176,6 +178,9 @@ class IndexFile extends BaseBinaryFile implements IndexableFile { } elseif (is_object($value) || is_resource($value)) { // Not wanted here throw new InvalidArgumentException(sprintf('value[]=%s is not stackable in files', gettype($value))); + } elseif (!($this->getIndexInstance() instanceof Indexable)) { + // Index instance not set + throw new BadMethodCallException('this->indexInstance[] is not properly set.'); } // Encode/convert the value into a "binary format" @@ -183,7 +188,7 @@ class IndexFile extends BaseBinaryFile implements IndexableFile { // Get a strong hash for the "encoded" data /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('INDEX-FILE: encoded=%s', $encoded)); - $hash = self::hash($encoded); + $hash = CryptoUtils::hash($encoded); // Then write it to the next free gap /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('INDEX-FILE: hash=%s', $hash)); diff --git a/framework/main/classes/file_directories/binary/stack/class_StackFile.php b/framework/main/classes/file_directories/binary/stack/class_StackFile.php index 26294f82..42a2412f 100644 --- a/framework/main/classes/file_directories/binary/stack/class_StackFile.php +++ b/framework/main/classes/file_directories/binary/stack/class_StackFile.php @@ -8,6 +8,7 @@ use Org\Mxchange\CoreFramework\Filesystem\Stack\FileStacker; use Org\Mxchange\CoreFramework\Filesystem\File\BaseBinaryFile; use Org\Mxchange\CoreFramework\Generic\UnsupportedOperationException; use Org\Mxchange\CoreFramework\Stack\File\StackableFile; +use Org\Mxchange\CoreFramework\Utils\Crypto\CryptoUtils; use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils; // Import SPL stuff @@ -180,7 +181,7 @@ class StackFile extends BaseBinaryFile implements FileStacker { $encoded = StringUtils::encodeData($value); // Get a strong hash for the "encoded" data - $hash = self::hash($encoded); + $hash = CryptoUtils::hash($encoded); // Then write it to the next free gap $data = $this->getStackInstance()->writeDataToFreeGap($stackName, $hash, $encoded); diff --git a/framework/main/classes/index/file/class_BaseFileIndex.php b/framework/main/classes/index/file/class_BaseFileIndex.php index 2b536cc4..16655594 100644 --- a/framework/main/classes/index/file/class_BaseFileIndex.php +++ b/framework/main/classes/index/file/class_BaseFileIndex.php @@ -99,7 +99,7 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer { $data = substr($data, 0, -1); // And update seek position - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->updateSeekPosition() ...'); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->updateSeekPosition() ...'); $this->getIteratorInstance()->getBinaryFileInstance()->updateSeekPosition(); /* @@ -163,7 +163,7 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer { ); // Write it to disk (header is always at seek position 0) - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->writeAtPosition(0, header=%s) ...', $header)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->writeAtPosition(0, header=%s) ...', $header)); $this->getIteratorInstance()->getBinaryFileInstance()->writeAtPosition(0, $header); // Trace message @@ -201,7 +201,7 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer { $this->getIteratorInstance()->getBinaryFileInstance()->setHeaderSize($headerSize); // Init counters and gaps array - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->initCountersGapsArray() ...'); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->initCountersGapsArray() ...'); $this->getIteratorInstance()->getBinaryFileInstance()->initCountersGapsArray(); // Default is not created @@ -210,11 +210,11 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer { // Is the file's header initialized? if (!$this->getIteratorInstance()->getBinaryFileInstance()->isFileHeaderInitialized()) { // First pre-allocate a bit - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->preAllocateFile(index) ...'); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->preAllocateFile(index) ...'); $this->getIteratorInstance()->getBinaryFileInstance()->preAllocateFile('index'); // Then write file header - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->createFileHeader() ...'); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->createFileHeader() ...'); $this->getIteratorInstance()->getBinaryFileInstance()->createFileHeader(); // Mark as freshly created @@ -229,7 +229,7 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer { /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: created=%d', intval($created))); if (!$created) { // Analyze file structure - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->analyzeFileStructure() ...'); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->analyzeFileStructure() ...'); $this->getIteratorInstance()->getBinaryFileInstance()->analyzeFileStructure(); } @@ -318,7 +318,7 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer { } // Call iterated object's method - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream)); $status = $this->getIteratorInstance()->getBinaryFileInstance()->writeAtPosition($seekPosition, $dataStream); // Return status diff --git a/framework/main/classes/index/file/stack/class_FileStackIndex.php b/framework/main/classes/index/file/stack/class_FileStackIndex.php index 799db1cb..517a9368 100644 --- a/framework/main/classes/index/file/stack/class_FileStackIndex.php +++ b/framework/main/classes/index/file/stack/class_FileStackIndex.php @@ -86,13 +86,13 @@ class FileStackIndex extends BaseFileIndex implements IndexableStack, Registerab throw new InvalidArgumentException('Parameter "data" is an empty array'); } elseif (!isset($data[StackableFile::ARRAY_NAME_HASH])) { // Important array element missing - throw new InvalidArgumentException(sprintf('data[%s] not found', $data[StackableFile::ARRAY_NAME_HASH])); + throw new InvalidArgumentException(sprintf('data[%s] not found', StackableFile::ARRAY_NAME_HASH)); } elseif (!isset($data[StackableFile::ARRAY_NAME_GAP_POSITION])) { // Important array element missing - throw new InvalidArgumentException(sprintf('data[%s] not found', $data[StackableFile::ARRAY_NAME_GAP_POSITION])); + throw new InvalidArgumentException(sprintf('data[%s] not found', StackableFile::ARRAY_NAME_GAP_POSITION)); } elseif (!isset($data[StackableFile::ARRAY_NAME_DATA_LENGTH])) { // Important array element missing - throw new InvalidArgumentException(sprintf('data[%s] not found', $data[StackableFile::ARRAY_NAME_DATA_LENGTH])); + throw new InvalidArgumentException(sprintf('data[%s] not found', StackableFile::ARRAY_NAME_DATA_LENGTH)); } // Raw data been written to the file @@ -105,10 +105,11 @@ class FileStackIndex extends BaseFileIndex implements IndexableStack, Registerab Indexable::SEPARATOR_GAP_LENGTH, $data[StackableFile::ARRAY_NAME_DATA_LENGTH] ); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: stackName=%s,hash=%s,rawData(%d)=%s', $stackName, $data[StackableFile::ARRAY_NAME_HASH], strlen($rawData), $rawData)); // Search for next free gap - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: stackName=%s,hash=%s,rawData()=%d', $stackName, $data[StackableFile::ARRAY_NAME_HASH], strlen($rawData))); - $gapPosition = $this->getIteratorInstance()->searchNextGap(strlen($rawData)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: Calling this->iteratorInstance->binaryFileInstance->searchNextGap(%d) ...', strlen($rawData))); + $gapPosition = $this->getIteratorInstance()->getBinaryFileInstance()->searchNextGap(strlen($rawData)); // Gap position cannot be smaller or equal than header length /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: stackName=%s,hash=%s,gapPosition=%s', $stackName, $data[StackableFile::ARRAY_NAME_HASH], $gapPosition)); @@ -118,8 +119,8 @@ class FileStackIndex extends BaseFileIndex implements IndexableStack, Registerab } // Then write the data at that gap - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: Calling this->iteratorInstance->writeData(%d,%s) ...', $gapPosition, $rawData)); - $this->getIteratorInstance()->writeData($gapPosition, $rawData); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: Calling this->iteratorInstance->binaryFileInstance->writeData(%d,%s) ...', $gapPosition, $rawData)); + $this->getIteratorInstance()->getBinaryFileInstance()->writeData($gapPosition, $rawData); // Trace message /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: stackName=%s,hash=%s,rawData()=%d - EXIT!', $stackName, $data[StackableFile::ARRAY_NAME_HASH], strlen($rawData))); diff --git a/framework/main/classes/stacker/file/class_BaseFileStack.php b/framework/main/classes/stacker/file/class_BaseFileStack.php index 0a2ca5ce..634eda30 100644 --- a/framework/main/classes/stacker/file/class_BaseFileStack.php +++ b/framework/main/classes/stacker/file/class_BaseFileStack.php @@ -135,7 +135,8 @@ abstract class BaseFileStack extends BaseStacker { ]); // Check if the array has only 3 elements - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: HEADER_STACK_ELEMENT_COUNT=%d,header(%d)=%s', BinaryFile::HEADER_STACK_ELEMENT_COUNT, count($header), print_r($header, true))); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: HEADER_STACK_ELEMENT_COUNT=%d,header()=%d', BinaryFile::HEADER_STACK_ELEMENT_COUNT, count($header))); + //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: HEADER_STACK_ELEMENT_COUNT=%d,header(%d)=%s', BinaryFile::HEADER_STACK_ELEMENT_COUNT, count($header), print_r($header, true))); if (count($header) != BinaryFile::HEADER_STACK_ELEMENT_COUNT) { // Header array count is not expected throw new UnexpectedValueException(sprintf('data=%s has %d elements, but expected is %d', diff --git a/framework/main/classes/utils/crypto/class_CryptoUtils.php b/framework/main/classes/utils/crypto/class_CryptoUtils.php new file mode 100644 index 00000000..3677b4e4 --- /dev/null +++ b/framework/main/classes/utils/crypto/class_CryptoUtils.php @@ -0,0 +1,93 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2021 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.shipsimu.org + * + * 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 . + */ +final class CryptoUtils extends BaseFrameworkSystem { + /** + * Length of output from hash() + */ + private static $hashLength = NULL; + + /** + * Private constructor, no instance needed. If PHP would have a static initializer ... + * + * @return void + */ + private function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Hashes a given string with a simple but stronger hash function (no salt) + * and hex-encode it. + * + * @param $str The string to be hashed + * @return $hash The hash from string $str + * @throws InvalidArgumentException If a parameter is not valid + * @throws LogicException If proper extension ext-mhash is not loaded + */ + public static final function hash (string $str) { + // Validate parameter/mhash extension + if (empty($str)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "str" is empty'); + } elseif (!extension_loaded('mhash')) { + // Should be there + throw new LogicException('Extension ext-mhash not loaded'); + } + + // Hash given string with (better secure) hasher + $hash = bin2hex(mhash(MHASH_SHA256, $str)); + + // Return it + return $hash; + } + + /** + * "Getter" for length of hash() output. This will be "cached" to speed up + * things. + * + * @return $length Length of hash() output + */ + public static final function getHashLength () { + // Is it cashed? + if (is_null(self::$hashLength)) { + // No, then hash a string and save its length. + self::$hashLength = strlen(self::hash('abc123')); + } + + // Return it + return self::$hashLength; + } + +} -- 2.39.5