独自の sha-256 ハッシュ アルゴリズムを PHP に実装してください。
ハッシュは「ハッシュ」とも呼ばれます。任意の長さの入力情報のセットを受け取り、ハッシュ アルゴリズムを通じてそれを固定長のデータ フィンガープリントに変換します。フィンガープリントはハッシュ値です。全体として、ハッシュはメッセージ ダイジェストと考えることができます。
PHP には文字列のハッシュ値を計算できる hash() という関数があり、興味本位でハッシュ計算の具体的な手順をググって、PHP を使って計算 sha-256 のセットを書きました。ハッシュ値のコード。もちろん、sha-256 以外にもハッシュ アルゴリズムはありますが、現在は sha-256 がより一般的に使用されています。以下は、現在米国国立標準技術研究所によってリリースされているハッシュ アルゴリズムです。
#ハッシュ アルゴリズム | 入力サイズ (ビット) | ブロック サイズ (ビット) | 行サイズ (ビット) | バイナリ長 (ビット) の生成 | 16 進長 (文字) の生成 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
< 2^64 | 512 | 32 | 160 | 40 | ||||||||
< 2^64 | 512 | 32 | 224 | 56 | ||||||||
< 2^64 | 512 | 32 | 256 | 64 | ||||||||
< 2^128 | 1024 | 64 | 384 | 96 | ||||||||
< 2^128 | 1024 | 64 | 512 | 128 | ##sha-512/224 | |||||||
1024 | 64 | 224 | 56 | ##sha-512/256 | ||||||||
1024 | 64 | 256 | 64 | ## |
- | $blocks[0] | $blocks[0] | - |
---|---|---|---|
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 | 01101000 01100101 01101100 01101100 01110010 01101100 01100100 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | 01101111 00100000 01110111 01101111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01011000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 |
/** * 步骤五:每一个512位切分区块,在区块末尾填充0,使得每个区块位数为2048位,经计算 * 每个区块还需要添加48x32个0 */ public function step5_split_blocks_and_append_48_lines(): void { $this->blocks = []; $append = $this->int2bits(0, 48 * 32); $len = count($this->bits); for ($i = 0; $i < $len; $i += 512) { $this->blocks[] = array_merge(array_slice($this->bits, $i, 512), $append); } }
步骤六:区块数据修改
上一步中我们给每一个区块末尾添加了很多 0,在这一步中,通过一些位操作将这些数据进一步调整。按 32 位为一行,我们需要修改新增加的 16-63 行的数据。修改的逻辑如下:
算法逻辑
For i from w[16…63]: s0 = (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3) s1 = (w[i-2] rightrotate 17) xor (w[i- 2] rightrotate 19) xor (w[i- 2] rightshift 10) w[i] = w[i-16] + s0 + w[i-7] + s1
其中 w 是每个区块的行数组,w[i] 就是第 i 行。
rightshift 是右移,rightrotate 是旋转右移, xor 是异或。
这里以第 16 行的处理为例:
算法详解
i = 16 (w[1] rightrotate 7) = 01101111001000000111011101101111 -> 11011110110111100100000011101110 (w[1] rightrotate 18) = 01101111001000000111011101101111 -> 00011101110110111101101111001000 (w[1] rightshift 3) = 01101111001000000111011101101111 -> 00001101111001000000111011101101 s0 = (w[1] rightrotate 7) xor (w[1] rightrotate 18) xor (w[1] rightshift 3) = 11001110111000011001010111001011 (w[14] rightrotate 17) = 00000000000000000000000000000000 -> 00000000000000000000000000000000 (w[14] rightrotate 19) = 00000000000000000000000000000000 -> 00000000000000000000000000000000 (w[14] rightshift 10) = 00000000000000000000000000000000 -> 00000000000000000000000000000000 s1 = (w[14] rightrotate 17) xor (w[14] rightrotate 19) xor (w[14] rightshift 10) = 00000000000000000000000000000000 w[i] = w[0] + s0 + w[9] + s1 = 00110111010001110000001000110111(相加得到的值如果超过 32 位,则抹去高位) /** * 步骤六:针对每一个2048位区块处理:以32位为一行,总共有64行,修改【16-63】行的数据, * 这【16-63】行就是上一步新增的48x32个0 */ public function step6_modify_blocks_appended_48_lines(): void { foreach ($this->blocks as &$block) { for ($i = 16; $i < 64; $i++) { $w0 = array_slice($block, ($i-16)*32, 32); $w1 = array_slice($block, ($i-15)*32, 32); $w9 = array_slice($block, ($i-7)*32, 32); $w14 = array_slice($block, ($i-2)*32, 32); $s0 = $this->xor( $this->rightRotate($w1, 7), $this->rightRotate($w1, 18), $this->rightShift($w1, 3) ); $s1 = $this->xor( $this->rightRotate($w14, 17), $this->rightRotate($w14, 19), $this->rightShift($w14, 10) ); $wi = $this->add($w0, $s0, $w9, $s1); // 如果$wi的长度超过了32位,则只取32位,舍弃高位 $k = count($wi) - 1; for ($j = $i * 32 + 31; $j >= $i * 32; $j--) { $block[$j] = $wi[$k] ?? 0; $k--; } } } }
步骤七:压缩
新建变量 $a、$b、$c、$d、$e、$f、$g、$h 值依次分别等于哈希常量 H[0-7],接着循环每一个区块的每一行,通过 与 非 异或 等操作将信息压缩到 $a、$b、$c、$d、$e、$f、$g、$h 中,最后将 $a、$b、$c、$d、$e、$f、$g、$h 的值与原始常量 H[0-7] 相加,拼接相加后的二进制结果 h0~h7 并转化为十六进制字符串得到最终的哈希值。
具体的压缩算法如下:
算法逻辑
For i from 0 to 63 s1 = (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25) ch = (e and f) xor ((not e) and g) temp1 = h + s1 + ch + k[i] + w[i] s0 = (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22) maj = (a and b) xor (a and c) xor (b and c) temp2 := s0 + maj h = g g = f f = e e = d + temp1 d = c c = b b = a a = temp1 + temp2
这里以第 0 行的处理为例,列出了变量计算结果方便大家对照调试:
计算结果
i = 0 s1 = 00110101100001110010011100101011 ch = 00011111100001011100100110001100 temp1 = 01011011110111010101100111010100 s0 = 11001110001000001011010001111110 maj = 00111010011011111110011001100111 temp2 = 00001000100100001001101011100101 h = 00011111100000111101100110101011 g = 10011011000001010110100010001100 f = 01010001000011100101001001111111 e = 00000001001011010100111100001110 d = 00111100011011101111001101110010 c = 10111011011001111010111010000101 b = 01101010000010011110011001100111 a = 01100100011011011111010010111001
/** * 步骤七:压缩数据 */ public function step7_compress_to_final_hash(): string { $a = $h0 = $this->int2bits(static::H[0], 32); $b = $h1 = $this->int2bits(static::H[1], 32); $c = $h2 = $this->int2bits(static::H[2], 32); $d = $h3 = $this->int2bits(static::H[3], 32); $e = $h4 = $this->int2bits(static::H[4], 32); $f = $h5 = $this->int2bits(static::H[5], 32); $g = $h6 = $this->int2bits(static::H[6], 32); $h = $h7 = $this->int2bits(static::H[7], 32); foreach ($this->blocks as $block) { for ($i = 0; $i < 64; $i++) { $s1 = $this->xor( $this->rightRotate($e, 6), $this->rightRotate($e, 11), $this->rightRotate($e, 25) ); $ch = $this->xor( $this->and($e, $f), $this->and($this->not($e), $g) ); $ki = $this->int2bits(static::K[$i], 32); $wi = array_slice($block, $i*32, 32); $temp1 = $this->add($h, $s1, $ch, $ki, $wi); $s0 = $this->xor( $this->rightRotate($a, 2), $this->rightRotate($a, 13), $this->rightRotate($a, 22), ); $maj = $this->xor( $this->and($a, $b), $this->and($a, $c), $this->and($b, $c) ); $temp2 = $this->add($s0, $maj); $h = $g; $g = $f; $f = $e; $e = $this->add($d, $temp1); $d = $c; $c = $b; $b = $a; $a = $this->add($temp1, $temp2); } } $h0 = $this->add($h0, $a); $h1 = $this->add($h1, $b); $h2 = $this->add($h2, $c); $h3 = $this->add($h3, $d); $h4 = $this->add($h4, $e); $h5 = $this->add($h5, $f); $h6 = $this->add($h6, $g); $h7 = $this->add($h7, $h); return $this->bits2hex(array_merge($h0, $h1, $h2, $h3, $h4, $h5, $h6, $h7)); }
至此整个哈希 sha-256 计算流程就完成了, 计算得到的哈希值也与 PHP 自带的 hash() 函数计算结果一致。
以上が独自の sha-256 ハッシュ アルゴリズムを PHP に実装してください。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

CakePHP は、PHP 用のオープンソース フレームワークです。これは、アプリケーションの開発、展開、保守をより簡単にすることを目的としています。 CakePHP は、強力かつ理解しやすい MVC のようなアーキテクチャに基づいています。モデル、ビュー、コントローラー

ファイルのアップロードを行うには、フォーム ヘルパーを使用します。ここではファイルアップロードの例を示します。

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

CakePHP はオープンソースの MVC フレームワークです。これにより、アプリケーションの開発、展開、保守がはるかに簡単になります。 CakePHP には、最も一般的なタスクの過負荷を軽減するためのライブラリが多数あります。

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります
