どうもこんにちは、Tadash です。
レガシー資産のモダナイゼーションでは、渡されるものがだいたい決まっています。ソースコードと、動いている実行ファイル。設計書はありません。書いた人はもういません。
この状態で「別の言語に移してほしい」と言われたとき、いきなり変換に手をつけると詰まります。何をする処理なのかが分からないまま書き換えても、合っているかどうかを判定できないからです。
今回は VB6 の OSS を1本題材にして、次の4手順を Bob Shell で通しました。
- 外部設計書を復元する
- 移行設計を決める
- 移植する
- 正しさを確かめる
結論から書くと、本家の公式テストと同じ結果が出るところまでは確認できました。そして最後に、移行でいちばん厄介な問題にぶつかりました。
その前に:正解値は決まっているか
着手前に次の2つが決まっているかどうかで、後の工程がすべて変わります。
- 入力と出力の仕様が確定していること
- その仕様に対する正解値が、移植元のコードの外で確定していること
移植したものが正しいかを確かめるには、「この入力なら、この出力になるはず」という正解が要ります。その正解が移植元のコードの中にしか無いと、結局コードを読んで期待値を決めることになり、実装が実装と一致しただけのテストができあがります。
正解値の出どころは何でもかまいません。規格の表、RFC のテストベクタ、同じ仕様の別実装、稼働中のシステムが出している実データ。どれかがあれば検証が成立します。
そして現実には、揃っていないほうが普通です。その場合は移植から始めるのではなく、正解値を確定させるところから始めます。動いている実行ファイルがあるなら、代表的な入力を流して出力を記録する。それも無いなら、業務側と詰めて仕様を決める。ここを飛ばすと、後の工程が全部「動いたように見える」で終わります。
今回は手順を最後まで通して見せたかったので、正解値が公開されているものを題材にしました。
題材:VbLessPass
選んだのは VbLessPass です。LessPass というパスワード生成方式の VB6 実装で、サイト名・ログイン名・マスターパスワードから、毎回同じパスワードを計算で導き出します。保存しないので、金庫が要りません。
- 本体は
mdPassword.basの1ファイル・191行(8.3 KB) - ライセンスは MIT
- 外に公開しているのは、関数2つ(
GeneratePassword()とDefPasswordProfile())と、設定を渡すための構造体1つだけ
入力と出力の仕様は単純です。サイト名・ログイン名・マスターパスワードとプロファイルを渡すと、パスワードの文字列が返る。それだけです。そして同じ入力からは必ず同じパスワードが出るうえ、本家 LessPass に公式のテストが公開されていて、期待するパスワードが直書きされています。つまり正解値が、コードの外で確定しています。
手作業でダウンロードしたのは、この .bas 1ファイルです。1行目は Attribute VB_Name = "mdPassword" で、これは VB6 がモジュールに付けるメタ情報です。移植先には持っていかない行で、こういう「言語処理系の都合で入っている行」を仕分けるのも移行作業の一部になります。
なお、このライブラリは暗号を自作していません。鍵導出(PBKDF2)は Windows の bcrypt.dll に投げています。ここは移植でも守るべき設計です。
最初の壁:元の環境が無い
始める前に、はっきりさせておくことがあります。
VB6 のコンパイラは、もう正規には手に入りません。 Visual Studio 6.0 は 2008 年にサポートが終了しています。Windows に標準で入っているのはランタイムだけで、ソースから実行ファイルを作る側はありません。互換をうたう処理系(twinBASIC など)はありますが、元のコンパイラそのものではないので、「元と同じ結果が出る」ことの根拠にはなりません。
つまり、移植元を動かして答え合わせをする、という一番素直なやり方が使えません。困った制約に見えますが、動いているものはあるがビルド環境はもう無い、という状況は現場でもよくあります。だからこそ、正解値を外に求める必要があります。
ひとつ補足しておくと、今回の mdPassword.bas は VBA7 向けの Declare PtrSafe を書き分けてあり、画面も持ちません。Excel の VBA に貼れば動く見込みはあります。VB6 と VBA は別の処理系なので「元と同じ」の証明にはなりませんが、比較対象としては有力です。今回は Python 側の手順を通すのが目的なので、そこまでやっていません。
手順①:外部設計書を復元する
最初にやるのは変換ではなく、コードを読んで仕様を起こすことです。
【Bob へのプロンプト(例)】
mdPassword.basを読んで、外部設計書を Markdown で書いてください。目次は「1. 概要/2. 公開インターフェース一覧/3. 入力仕様/4. 出力仕様/5. 処理の流れ/6. 外部依存(VB6 ランタイム・Windows API)/7. 制約とエラー時の挙動」。2 にはPublicの関数だけでなく、定数・ユーザー定義型・列挙もすべて含めてください(関数は名前・引数・戻り値・役割)。実装の行単位の説明ではなく、外から使う人に必要な情報を書いてください。推測が入る箇所は「推定」と明記してください。
10.4 KB の設計書が出てきました。公開インターフェースの節はこうなっています(抜粋)。
2.1 ユーザー定義型
LessPasswordProfile
フィールド名 型 説明 Lowercase Boolean 小文字(a-z)を含めるかどうか Uppercase Boolean 大文字(A-Z)を含めるかどうか Digits Boolean 数字(0-9)を含めるかどうか Symbols Boolean 記号を含めるかどうか Length Long 生成するパスワードの長さ(文字数) Counter Long パスワードカウンター Exclude String 除外する文字列 Hash String 使用するハッシュアルゴリズム名(例: "SHA256") Iterations Long PBKDF2の反復回数 KeySize Long 導出する鍵のサイズ(バイト数) 2.2 公開関数
GeneratePassword()
指定されたサイト、ログイン、マスターパスワード、およびプロファイルに基づいて、決定論的なパスワードを生成します。同じ入力パラメータを使用すれば、常に同じパスワードが生成されます。
プロンプトで「公開関数だけでなく、型もすべて」と指定したのは、これを出させるためです。このライブラリで外から触るものの実体は、関数ではなくこの構造体で、ここが抜けると次の工程で移植の形が決まりません。
そして外部依存の節。VB6 のコードは、言語仕様と OS の機能が地続きになっています。
6.1 Windows API
bcrypt.dll
API関数 用途 BCryptOpenAlgorithmProvider ハッシュアルゴリズムプロバイダーの初期化 BCryptCloseAlgorithmProvider プロバイダーのクローズ BCryptDeriveKeyPBKDF2 PBKDF2による鍵導出の実行 要件: Windows Vista以降(bcrypt.dllが標準で利用可能)
kernel32.dll
API関数 用途 WideCharToMultiByte Unicode文字列からUTF-8バイト配列への変換
Windows API が4本。ここが移植で最初にぶつかる壁になります。用途まで書き出させておくと、次の工程で「何に置き換えるか」を決める材料になります。
手順②:移行設計を決める
次に、どう移すかを先に文書化します。実装を始めてから毎回判断していると、書き手(今回は AI)がブレます。
【Bob へのプロンプト(例)】
外部設計書をもとに、VB6 から Python への移行設計書を書いてください。次の4点を必ず含めてください。
(1)標準関数・構文の対応表(VB6 の書き方 → Python の書き方 → 注意点)。Windows API 呼び出しを何に置き換えるかも表にすること
(2)型と添字の扱い(Integer/Long のビット幅、オーバーフロー、配列の下限、String の文字コード、バイト配列の扱い)
(3)コーディング規約(PEP 8 準拠、命名、型ヒント、モジュール構成、公開 API の名前をどうするか)
(4)コメント方針(コメントは日本語で書く。元コードのコメントも訳す。ただし冒頭のライセンスヘッダは訳さず原文のまま残す)
判断に迷う点は選択肢と推奨を併記してください。
19.3 KB の移行設計書になりました。要点だけ書きます。
OS 依存の置き換えが山場
このファイルで一番大きい判断がここです。VB6 側は Windows API を直接呼んでいますが、Python には標準ライブラリがあります。
| VB6 | Python |
|---|---|
BCryptDeriveKeyPBKDF2(bcrypt.dll) |
hashlib.pbkdf2_hmac |
WideCharToMultiByte(CP_UTF8 指定) |
str.encode("utf-8") |
BCryptOpenAlgorithmProvider / Close
|
不要(ハンドル管理そのものが消える) |
API 3本が標準ライブラリの1行になり、後始末のコードごと消えます。 移行でコードが目に見えて減るのは、こういう箇所です。
逐語訳しないほうがいい箇所もある
型の対応表には、こう書かれていました。
2.1 整数型のビット幅とオーバーフロー
VB6型 ビット幅 Python型 ビット幅 注意点 Integer16ビット符号付き int任意精度 Pythonは自動拡張、オーバーフローなし Long32ビット符号付き int任意精度 同上 Byte8ビット符号なし int任意精度 範囲チェックが必要な場合は明示的に実装
この違いが、次の判断につながります。このライブラリには、バイト配列を手作りで割り算していく処理(pvDivMod)が入っています。VB6 には大きな整数を扱う型が無いので、自前で筆算しているわけです。Python の整数は任意精度なので、素直に書けばこの関数は要らなくなります。
ただし、消せるからといって黙って消すと危ない。だから移行設計に「どこを逐語訳し、どこを言語の機能に置き換えるか」を書き残します。手順④で差が出たとき、原因を探す起点になります。
今回はここを逐語訳に倒したので、移植版にも _div_mod が同じ形で残りました。この選択があとで意味を持ちます。元コードの割り算の癖が、そのまま移植版にも引き継がれたからです。
一番の罠
元のコードには、こう書かれた行があります。
uProfile.Iterations / 10000@
1万で割っています。 これは VB6 に64ビット整数が無いための回避策で、Currency 型の内部表現が実値の1万倍になる性質を使い、API には正しい 100000 を渡しています。
ここを字面どおり「1万で割る」と移植すると、反復回数が10回になり、出てくるパスワードが全部変わります。しかも例外は出ません。静かに全滅します。こういう箇所こそ、移行設計で先に潰しておく価値があります。
コメントは日本語にする
移行のついでに済ませておきたいのが、コメントの日本語化です。移した後のコードを読むのは日本の保守担当者で、原文のコメントは英語です。せっかく AI に通すのだから、同じ工程で訳させます。
これは親切ではなく、成果物の質の話です。移行後のコードが読めなければ、結局また属人化します。目的が「新しい言語にすること」ではなく「保守できる状態にすること」なら、コメントは成果物の一部です。
ただしライセンスヘッダは訳しません。 別の言語に書き換えても、元の著作権表示を改変したり消したりしてよいことにはなりません。
手順③:移植する
設計書と移行設計ができたら、ようやく変換です。
【Bob へのプロンプト(例)】
外部設計書と移行設計書に従って、mdPassword.basを Python に移植してください。
(1)移行設計の対応表と規約から外れる書き方はしないでください。
(2)関数単位で、元の VB6 の関数名を日本語コメントで併記してください。
(3)元の挙動を変えないでください。元のコードが異常終了する入力は、移植版でも同じように異常終了させてください。エラー処理やバリデーションを新たに追加しないでください。
(4)改善したほうがよいと思った点は、コードに反映せず「改善提案」として別に列挙してください。
(3)が要ります。 移植で一番危ないのは、バグの作り込みではなく良かれと思った改善です。
古いコードには、変な入力を渡すと落ちる箇所が残っています。それを見つけると、直したくなります。ところが移行では、落ちる挙動も仕様のうちです。勝手に例外処理を足すと、元は落ちていた入力が通るようになり、挙動が静かに変わります。エラーが出るわけではないので、記録には何も残りません。
かといって、気づきを捨てさせるのはもったいない。だから(4)で、コードの外に出させます。移行と改善は別の仕事で、まとめてやると、どちらが原因で何が変わったのか分からなくなります。
出てきたコード
一番差が出た関数を並べます。鍵導出の部分です。
移植前(VB6)
Private Function pvCalcEntropy(sSite As String, sLogin As String, sMasterPassword As String, uProfile As LessPasswordProfile) As Byte()
Const BCRYPT_ALG_HANDLE_HMAC_FLAG As Long = 8
Dim hShaAlg As Long
' ...
hResult = BCryptOpenAlgorithmProvider(hShaAlg, StrPtr(uProfile.Hash), StrPtr("Microsoft Primitive Provider"), BCRYPT_ALG_HANDLE_HMAC_FLAG)
If hResult < 0 Then
sApiName = "BCryptOpenAlgorithmProvider"
GoTo QH
End If
baPass = ToUtf8Array(sMasterPassword)
baSalt = ToUtf8Array(sSite & sLogin & LCase$(Hex$(uProfile.Counter)))
ReDim baRetVal(0 To uProfile.KeySize - 1) As Byte
hResult = BCryptDeriveKeyPBKDF2(hShaAlg, baPass(0), UBound(baPass) + 1, baSalt(0), UBound(baSalt) + 1, uProfile.Iterations / 10000@, baRetVal(0), UBound(baRetVal) + 1, 0)
If hResult < 0 Then
sApiName = "BCryptDeriveKeyPBKDF2"
GoTo QH
End If
pvCalcEntropy = baRetVal
QH:
If hShaAlg <> 0 Then
Call BCryptCloseAlgorithmProvider(hShaAlg, 0)
End If
' ...
End Function
移植後(Python)
def _calc_entropy(
site: str,
login: str,
master_password: str,
profile: PasswordProfile
) -> bytearray:
"""エントロピーを計算
VB6: pvCalcEntropy
"""
# パスワードとソルトをUTF-8バイト列に変換
password_bytes = _to_utf8_bytes(master_password)
salt_text = site + login + hex(profile.counter)[2:].lower()
salt_bytes = _to_utf8_bytes(salt_text)
# ハッシュアルゴリズム名を正規化(VB6では"SHA256"、Pythonでは"sha256")
hash_name = profile.hash_algorithm.lower().replace("-", "")
# PBKDF2で鍵を導出
# VB6では iterations / 10000 を Currency型で処理
# Pythonでは直接 iterations を使用
iterations = profile.iterations
try:
derived_key = hashlib.pbkdf2_hmac(
hash_name, password_bytes, salt_bytes, iterations, dklen=profile.key_size
)
except ValueError as e:
raise ValueError(f"無効なハッシュアルゴリズム: {profile.hash_algorithm}") from e
return bytearray(derived_key)
GoTo QH によるハンドルの後始末が消え、API 3本が標準ライブラリの呼び出し1つになりました(読みやすさのため docstring は省いています)。そして例の1万割りは、移植元がどう書いていたかがコメントに残ったうえで、正しい値が渡されています。
try で包んでいる部分は、エラー処理を新しく足したものではありません。元の VB6 もハッシュ名が不正なら BCryptOpenAlgorithmProvider が失敗して Err.Raise します。エラーになるかどうかは変えず、メッセージだけ移植先の書き方に合わせた形です。
コードに入らなかった提案
改善提案.md が別に出てきました。18.7 KB、8カテゴリです。見出しの一部を挙げます。
- 1.1 入力バリデーションの追加
- 1.3 除外文字による文字セット枯渇の検出
- 2.1 メモリ上の機密情報の消去
- 2.3 反復回数の推奨値の更新
- 6.1 互換性テストの追加
1.3 にはこう書かれていました。
現状: 除外文字によってすべての文字が削除された場合、空の文字セットで処理が続行される。
_consume_entropyで無限ループまたはゼロ除算エラーが発生する可能性
気づいてはいたが、コードには入れなかったわけです。これがやりたかったことでした。AI の判断力を殺さずに、勝手な変更だけを止められています。
手順④:正しさを確かめる
元の実行ファイルが作れないので、「元と同じ結果になった」を直接は証明できません。では何と比べるか。手順①の外部設計書と、外に公開されている正解です。
【Bob へのプロンプト(例)】
移植した Python 実装が正しく動くかを検証してください。検証だけを行い、移植したコードは修正しないでください。誤りが見つかっても直さず、報告だけしてください。
(1)まず外部設計書に戻り、公開されている機能ごとに「どんな入力に対して、どんな結果になれば正しいか」を先に決めてください。
(2)正解値の根拠にしてよいのは、外部設計書・移植元のmdPassword.bas・LessPass の公開仕様や公式実装です。移植版の Python コードを読んで正解値を決めないでください。何を根拠にしたのかを、機能ごとに必ず書いてください。
(3)移植元が異常終了する入力は、移植版も同じように異常終了するのが正解です。移植版のほうがきれいなエラーを返すなら、それは不一致として報告してください。
(4)決めた正解値をもとにテストケースを作ってください。正常系だけでなく、境界値と異常系も入れてください。
(5)本家 LessPass と同じ入力から同じパスワードが出るかを突き合わせてください。参照になる実装が手元に無ければ、何を入れれば比較できるかを提示してから進めてください。
(6)テストは合否を自動で判定できる形で書き、失敗した件数を終了コードで返してください。画面に出力するだけで判定しない書き方はしないでください。
(7)実行して、結果を 検証結果.md に UTF-8 で書き出してください。全ケースを表にして、省略も件数の丸めもしないでください。
(8)正解値を決められなかった機能があれば、「検証できなかった」として理由とともに列挙してください。推測で通ったことにしないでください。
仕掛けの1つ目が(2)です。正解値を、移植したコードを読んで決めさせない。 ここを縛らないと、実装から期待値を起こして必ず通るテストができあがります。全件通っても、実装が実装と一致しただけです。あわせて、何を読んでよいのかまで書きます。移植元のソースは読ませます。等価性を見るのだから、そこが最良の根拠です。
2つ目は、冒頭に置いた修正禁止の一文です。手順③でも同じ縛りをかけていますが、ここでも改めて書きます。検証は差異を見つける工程なので、直したくなる場面が最も多くなります。
3つ目が(3)で、ここは直感に反します。元が異常終了する入力に対して、移植版がきれいなエラー(入力を検証して、理由の分かる例外を返すこと)で応じたら、普通は改善ですが、移行では不一致です。この一文が無いと、正しく移植できているほうが不合格になりかねません。
途中で聞いてきた
流したあと、Bob はいきなり書き始めず、質問を返してきました。
検証を進めるために、VB6版(mdPassword.bas)の実際の動作を確認する必要があります。以下のいずれかの方法で正解値を取得できますか?
- VB6環境で実行
- 既存のテスト結果
- 本家 LessPass との比較
(5)に「参照が手元に無ければ提示してから進めて」と書いておいたので、勝手に何かを導入せず、判断をこちらに返してきました。ここで本家の公式テストの場所を教えました。そのファイルは GPL-3.0 なのでコピーせず、入力と期待値だけを引用するよう添えています(移植先は MIT なので混ぜられません)。
結果
| 区分 | 結果 |
|---|---|
| 正常系(本家の公式テストと突合) | 6 / 6 |
| 境界値 | 6 / 7 |
| 異常系 | 4 / 4 |
正常系は全一致でした。 本家の公式テストに直書きされている期待値と、移植版の出力が一致しています。
| 入力 | 期待値 | 実際 |
|---|---|---|
| example.org / 16文字 / counter=1 | WHLpUL)e00[iHR+w |
WHLpUL)e00[iHR+w |
| example.org / 14文字・記号なし / counter=2 | MBAsB7b1Prt8Sl |
MBAsB7b1Prt8Sl |
| example.org / 16文字・数字のみ | 8742368585200667 |
8742368585200667 |
♥ LessPass ♥ / 16文字 |
BH$>U5Lj7v9A1wB/ |
BH$>U5Lj7v9A1wB/ |
注目したいのは最後の1件です。ASCII だけの入力は、文字コードの扱いを取り違えても同じバイト列になるので差が出ません。サイト名に ♥ が入るこの1件だけが、WideCharToMultiByte を str.encode("utf-8") に置き換えた判断の当否を判定できます。例の1万割りのほうは、間違えていれば6件とも外れます。
そして Bob は、確かめられなかった範囲も出してきました。
検証できなかった項目
境界値テスト … 理由: VB6版での実行結果が必要/該当ケース: 7件すべて
VB6版との完全互換性 … 理由: VB6版を実行して、すべての入力パターンで出力が一致することを確認する必要がある/該当ケース: すべてのテストケース
エラーハンドリングの互換性 … 理由: VB6版が異常終了する入力で、Python版も同じように異常終了するかを確認する必要がある
公式テストで担保できるのは、そこに書かれた入力だけです。それ以外は「確認できていない」。この線引きが出てきたのは、(8)を入れたからです。
見つけたバグを、どう扱うか
NG になった1件の話をします。移行で厄介なのは、ここから先です。
不合格になったのは、文字種4つ・長さ4 のケースです。ZeroDivisionError で落ちました。
テスト側は「文字種が4つあるなら、長さ4までは生成できるはず」という前提で期待値を置いていました。では実際はどうか。元の VB6 を読むと、こうなっています。
'--- generate initial password
pvRenderPassword = pvConsumeEntropy(baEntropy, sSetOfChars, uProfile.Length - UBound(vRules) - 1)
' ...
'--- insert strings pseudo-randomly
For lIdx = 1 To Len(sCharsToAdd)
lRemainder = pvDivMod(baEntropy, Len(pvRenderPassword))
vRules は有効にした文字種の配列で、4種なら UBound は 3。最初に作る文字数は 4 - 3 - 1 = 0 です。つまり pvRenderPassword は空のまま2つ目のループに来て、Len("") は 0。割る数が 0 になります。元の VB6 も、同じ入力で0除算で落ちます。
移植版も同じです。手順②で pvDivMod を逐語訳に決めていたので、割る数が 0 になる経路がそのまま残っています。
一方で、テストが置いた期待値は、仕様から見れば妥当です。文字種が4つあって長さ4なら、4文字のパスワードが返るべきで、返らないのは実装の側です。この NG が指しているのは、移植のミスではなく、元コードに元からあるバグでした。移植版は、それを忠実に再現しています。
移植としては正解で、プログラムとしては欠陥。では直すべきか。
- 直すと、等価性が崩れます。 元は落ちる入力が、移植版では通る。移行の成果物としては別物になります
- 直さないと、欠陥が残ります。 分かっていて放置した、という記録が残ります
そして、これは移行チームだけで決められません。その入力が業務で発生するのか、落ちたときに何が起きるのか、直すとして誰が受け入れテストをするのか。全部、移行の外側の話です。
だから移行工程での正解は、直さずに、見つけたものを台帳にすることだと考えています。改善は移行が終わってから、差分が見える状態で議論する。今回それができたのは、③と④の両方に「修正するな」と書いておいたからです。書いていなければ、その場で直されて、判断の機会そのものが消えていました。
もうひとつ。AI が出した合否は、そのままでは受け取れません。 今回の 検証結果.md は「1件のテストが失敗しました」で始まり、「修正が必要です」で終わっています。指示どおりに直せば、壊れるのは等価性のほうです。だから(2)で「何を根拠にしたか書け」と指示しています。合否ではなく根拠を読む。人間の仕事はそこに移ります。
分かったこと
4手順は、題材が変わっても同じです。 復元 → 方針 → 移植 → 検証。手順が同じということは、型にできるということです。次のレガシーが来たときに、プロンプトごと使い回せます。移行を1回こっきりの職人仕事から、手順書のある作業に変えられます。
変換そのものは、作業の真ん中の一部でしかありません。 VB6 のコードを別の言語へ変換する専用ツールは以前からあり、高い自動変換率をうたう製品もあります。変換という工程だけを見れば、決定的で再現性のある専用ツールのほうが向いています。AI は非決定的で、同じ指示でも出力が揺れます。
それでも汎用の AI エージェントを使う意味があるのは、変換の前後を同じ道具で通せるからです。前は失われた仕様の復元、後はテストと検証。専用ツールが受け持つのは真ん中だけで、その前後を埋める相手がいません。だから、どちらかを選ぶ話ではなく、変換は専用ツール・前後は AI エージェント、という組み方が現実的だと考えています。
そして、書き方の方針はできるだけ変えない。 移植元が OS に任せていた処理は、移植先でも標準ライブラリに任せます。言語が変われば書き方は変わりますが、元の設計判断まで作り直す必要はありません。移行は書き直しの機会ですが、自分で書く量を増やす機会ではありません。
まとめ
- 着手前に、入力と出力の仕様と正解値が確定しているかを確かめます。無ければ、そこを決めるところから始めます。
- 設計書の無いレガシーは、変換より先に仕様の復元から入ります。
- 勝手に直させない。移植でも検証でも、これを外すと差異が記録に残りません。
- 見つけた欠陥は直さずに台帳へ。直すかどうかは移行の外側の判断です。
移行の価値は、動くものが増えることではなく、読めるものに変わることにあると考えています。今回できたのは移植と、正常系が本家と一致することの確認まで。残りは「確認できていない」と書いて残しました。そこまで書いて、やっと移行の成果物になると考えています。
※2026-07-25 時点。題材は公開されている OSS(VbLessPass=MIT)で、業務での適用を述べたものではありません。検証に使った本家 LessPass の公式テストは GPL-3.0 のため、入力と期待値のみを引用しています。VB6 のコンパイラが入手できないため、VB6 でビルドしたものとの直接比較は行っていません(VBA で動かしての比較も未実施です)。パスワードを扱うライブラリを題材にしていますが、暗号処理の自作を勧めるものではありません。
出典
- VbLessPass | GitHub(MIT)
- LessPass | GitHub(移植元の方式・公式テストは GPL-3.0)
- BCryptDeriveKeyPBKDF2 | Microsoft Learn
- hashlib | Python 標準ライブラリ
※投稿内容は個人の見解であり、必ずしも私の所属団体・企業における立場、戦略、意見を代表するものではありません。
