Part I: 逐次処理¶
概要¶
本章では、パスワードクラッキングを例に逐次処理の基礎を学びます。
パスワードクラッカーの実装¶
組み合わせ生成¶
object PasswordCracker:
private val Letters: String = "abcdefghijklmnopqrstuvwxyz"
/** Generate all combinations of lowercase letters of the given length */
def getCombinations(length: Int): List[String] =
@tailrec
def generate(current: List[String], remaining: Int): List[String] =
if remaining == 0 then current
else
val next = for
prefix <- current
letter <- Letters
yield prefix + letter
generate(next, remaining - 1)
generate(List(""), length)
ハッシュ計算¶
import java.security.MessageDigest
/** Calculate SHA-256 hash of the given password */
def getCryptoHash(password: String): String =
val digest = MessageDigest.getInstance("SHA-256")
val bytes = digest.digest(password.getBytes("UTF-8"))
bytes.map(b => f"$b%02x").mkString
パスワード解析¶
/** Check if the password matches the given hash */
def checkPassword(password: String, cryptoHash: String): Boolean =
getCryptoHash(password) == cryptoHash
/** Crack password by brute force */
def crackPassword(cryptoHash: String, length: Int): Option[String] =
getCombinations(length).find(checkPassword(_, cryptoHash))
特徴¶
- 末尾再帰:
@tailrecアノテーションでスタックオーバーフローを防止 - for 内包表記: 宣言的な組み合わせ生成
- Option 型: null の代わりに
Option[String]で結果を表現
次のステップ¶
Part II では、スレッドを使った並列処理を学びます。