パスワード生成ツールに直感的なコントロール機能を追加した(パスカエール開発記)

  • パスワード生成ツールにスライダーとチェックボックスを追加したら、設定変更のたびに新しいパスワードが生成されて元のが消える問題が発生。
  • 解決策は最大文字数で生成して内部保存し、表示時に設定に応じて切り詰める方式にすること。
  • これで設定を変えても気に入ったパスワードが失われません。
パスワード生成ツール コントロール機能追加 従来の問題 設定変更のたびに 新しいパスワード生成 元のパスワードが消失 解決策 最大文字数で生成 内部に保存 元データを保持 表示時に設定適用 結果 設定変更しても パスワード保持 ユーザビリティ向上 追加したコントロール機能 チェックボックス 記号表示 ON/OFF 大文字小文字切り替え スライダー 文字数調整 10-16文字 子音・母音交互 読みやすい文字列 覚えやすさ向上

追加した機能の概要

パスワード生成ツール「パスカエール」の続きです。前回の基本機能に加えて、ユーザーが自分好みにカスタマイズできる機能を実装しました。記号の表示切り替え、大文字小文字の制御、文字数調整など、実用的なコントロール機能の開発過程を共有します。

今回のアップデートでは、3つの主要な機能を追加しました。

追加した機能の概要 記号表示切り替え チェックボックスで 記号のON/OFF制御 一部サービスの制限に対応 大文字小文字切り替え 英字部分の最初の文字を 大文字⇔小文字で切り替え パスワードポリシーに対応 文字数調整 スライダーで 10-16文字に調整 要件に応じた長さ設定 読みやすいパスワード生成の改良 子音と母音を交互に配置する方式に変更 完全ランダムから発音しやすい文字列へ(例:koda、femi)
  • 記号表示の切り替え機能では、チェックボックスのオンオフで記号を表示したり隠したりできます。
  • 大文字小文字の切り替え機能は、英字部分の最初の文字を大文字と小文字で切り替えられます。
  • 文字数調整スライダーでは、パスワード全体の長さを8文字から24文字まで自由に変更できます。

英字部分は子音と母音を交互に配置

英字部分の生成方法を大幅に改良しました。これまでの完全ランダムから、子音と母音を交互に配置する方式に変更しています。

読みやすいパスワード生成の改良 Before: 完全ランダム 生成例 kxfqmz qzwxvp jxklmf 覚えにくい・発音困難 After: 子音・母音交互 生成例 koda femi banu 発音しやすい・覚えやすい 実装 子音: bcdfghjkmnpqrstvwxyz / 母音: aeiou / 交互配置で自然な音韻生成
const consonants = "bcdfghjkmnpqrstvwxyz"; // 子音(lを除外)
const vowels = "aeiou"; // 母音

function generateLetterPart(letterCount) {
    let letters = "";
    const startWithConsonant = Math.random() < 0.5;
    
    for (let i = 0; i < letterCount; i++) {
        const isConsonantTurn = startWithConsonant ? (i % 2 === 0) : (i % 2 === 1);
        if (isConsonantTurn) {
            letters += getRandomChar(consonants);
        } else {
            letters += getRandomChar(vowels);
        }
    }
    
    return letters;
}
Code language: JavaScript (javascript)

子音と母音を交互に配置すると、発音しやすい文字列が生成されます1例えば「koda」や「femi」のような組み合わせができあがります。完全にランダムな「kxfq」のような文字列と比べて、覚えやすさが向上します。

開始を子音にするか母音にするかは50%の確率で決まります。これにより生成パターンに多様性を保ちます。ランダム生成には、簡易的に Math.random()を使用2しています。

英字部分の文字数を拡張

英字部分の文字数も4文字から6文字に拡張しました。読みやすさと安全性のバランスを考慮した調整です。

// 英字4-6文字(子音・母音交互)
const letterCount = 4 + Math.floor(Math.random() * 3); // 4-6文字
Code language: JavaScript (javascript)

4文字では少し短く感じられ、6文字を超えると覚えにくくなります。この範囲が実用的な長さです。

動的な表示制御の仕組み

最も技術的に興味深い部分は、パスワードの動的な表示制御です。従来の方式では設定変更のたびにパスワードを再生成していましたが、これでは元のパスワードが失われてしまいます。

動的な表示制御の仕組み 従来方式 設定変更時 パスワード再生成 元データが失われる 新方式 最大文字数で生成 内部に保存 元データを保持 表示処理 設定に応じて 加工・表示 リアルタイム更新 実装の流れ 1 currentPasswords配列に保存 2 toggleDisplay()で再表示制御 3 getDisplayPassword()で表示用パスワード生成

新しい方式では、最大文字数(16文字)でパスワードを生成し、内部に保存します。表示時に必要な長さまで切り詰める仕組みです。

let currentPasswords = []; // 現在のパスワードデータを保存

function generatePassword() {
    // 最大16文字でパスワード生成
    const maxNumberCount = 16 - 1 - letterCount; // 記号1文字+英字を除いた残り
    const numberPart = generateNumberPart(maxNumberCount);
    password += numberPart.formatted;
    
    return {
        password: password,
        breakdown: breakdown,
        baseNumbers: numberPart.base
    };
}
Code language: JavaScript (javascript)

生成したパスワードはcurrentPasswords配列に保存されます。設定が変更されても、この元データは保持されます。

表示時の処理では、設定に応じてパスワードを加工します。

function getDisplayPassword(password) {
    const symbolToggle = document.getElementById('symbolToggle').checked;
    const uppercaseToggle = document.getElementById('uppercaseToggle').checked;
    const targetLength = parseInt(document.getElementById('numberCountSlider').value);
    
    // 指定文字数まで切り詰め
    let result = password.substring(0, targetLength);
    
    // 大文字制御(英字の最初の文字=全体の2文字目)
    if (!uppercaseToggle && result.length > 1) {
        const symbolPart = result[0];
        const firstLetter = result[1].toLowerCase();
        const rest = result.slice(2);
        result = symbolPart + firstLetter + rest;
    }
    
    return result;
}
Code language: JavaScript (javascript)

この関数は3つの処理を順番に実行します。まず、スライダーで指定された文字数まで文字列を切り詰めます。次に、大文字チェックボックスがオフの場合、英字の最初の文字(全体の2文字目)を小文字に変換します。最後に、加工済みの文字列を返します。

UIコントロール部分の実装

HTML構造はシンプルに設計しました。ボタンの下に配置したコントロール部分は、2つの行に分けて整理しています。

UIコントロール部分の実装 HTML構造 <div class=”controls”> <div class=”control-row”> <input type=”checkbox”> <input type=”range”> </div> CSS設計 Flexboxで横並び配置 display: flex; justify-content: space-between; チェックボックス間のスペース均等配分 レスポンシブデザイン 画面幅600px以下でレイアウト変更 デスクトップ:横並び モバイル:縦並び 視覚的に区別された背景色とコントロール要素の配置
<div class="controls">
    <div class="control-row">
        <label class="checkbox-label">
            <input type="checkbox" id="symbolToggle" checked onchange="toggleDisplay()">
            記号
        </label>
        <label class="checkbox-label">
            <input type="checkbox" id="uppercaseToggle" checked onchange="toggleDisplay()">
            大文字
        </label>
    </div>
    <div class="control-row">
        <label class="slider-label">
            字数: <span id="numberCountValue">16</span>
            <input type="range" id="numberCountSlider" min="10" max="16" value="16" onchange="adjustPasswordLength()">
        </label>
    </div>
</div>
Code language: HTML, XML (xml)

1行目には記号と大文字のチェックボックスを横並びで配置しました。2行目には <input type=”range”>3を使って、文字数調整のスライダーを設置しています。

CSSでは、コントロール要素の見た目を整えています。

.controls {
    margin: 20px 0;
    padding: 16px;
    background: #f7fafc;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
}

.control-row {
    display: flex;
    gap: 20px;
    margin-bottom: 12px;
    align-items: center;
    flex-wrap: wrap;
    justify-content: space-between;
}
Code language: CSS (css)

背景色を薄いグレーにして、コントロール部分を視覚的に区別しています。display: flex4で横並びにして、justify-content: space-betweenで、チェックボックス間のスペースを均等に配分しました。

記号表示の切り替え機能

記号の表示切り替えは、CSSのdisplayプロパティを利用しています。記号部分は常に生成されますが、表示のオンオフを制御します。

// 記号部分
if (symbolToggle) {
    coloredPassword += `<span class="symbol">${password.substr(index, breakdown.symbol)}</span>`;
    index += breakdown.symbol;
} else {
    coloredPassword += `<span class="symbol" style="display:none">${password.substr(index, breakdown.symbol)}</span>`;
    index += breakdown.symbol;
}
Code language: HTML, XML (xml)

記号がオフの場合でも、HTML要素は存在し続けます。display:noneで見た目から隠すだけです。この方式により、記号をオンに戻したときに元の記号が復活します。

スライダーによる文字数制御

文字数調整スライダーは、リアルタイムで変更を反映します。スライダーを動かすたびにadjustPasswordLength関数が呼び出されます。

スライダーによる文字数制御 文字数調整スライダー 10文字 14文字 16文字 文字数による表示例 10文字 !Koda23045 14文字 !Koda23045678 16文字 !Koda2304567890 最大16文字で生成し、表示時に指定文字数まで切り詰め 再生成せずに長さ変更が可能
function adjustPasswordLength() {
    const slider = document.getElementById('numberCountSlider');
    const valueDisplay = document.getElementById('numberCountValue');
    valueDisplay.textContent = slider.value;
    
    // 既存のパスワードの表示長を調整
    toggleDisplay();
}
Code language: JavaScript (javascript)

スライダーの値をスパン要素に表示し、toggleDisplay関数を呼び出して画面を更新します。この仕組みにより、パスワードを再生成せずに長さを変更できます。数字部分の3文字ごとに0を挿入するルールは維持しています。視認性を高める重要な機能だからです。文字数が変わっても、このパターンは保たれます。

まとめ

パスワード生成ツールに3つのコントロール機能を追加しました。記号表示の切り替え、大文字小文字の制御、文字数調整により、ユーザーのニーズに柔軟に対応できるようになりました。子音と母音を交互に配置する方式で、読みやすさも向上しています。元データを保持し表示時に加工する仕組みにより、設定変更時もパスワードが失われない設計を実現しました。

  1. JavaScript Password Generator – GeeksforGeeks – JavaScript での基本的なパスワード生成方法とチェックボックス制御の実装方法
  2. HTML input type=”range” – MDN Web Docs – HTML5 range スライダーの公式仕様とイベント処理に関する詳細な説明
  3. How To Create Range Sliders – W3Schools – レンジスライダーのスタイリングと JavaScript での値表示更新のコード例
  4. Password Generator using JavaScript – Scaler – パスワード生成アプリケーションの構造化された実装アプローチと UI 設計パターン
  5. Basic concepts of flexbox – MDN Web Docs – CSS Flexbox の基本概念と main axis、cross axis の詳細解説
  6. CSS Flexbox Responsive – W3Schools – Flexbox を使用したレスポンシブデザインの実装方法とメディアクエリとの組み合わせ
  7. Creating A Custom Range Input – Smashing Magazine – ブラウザ間で一貫した見た目を実現するカスタムレンジ入力のスタイリング技法
  1. 認知心理学の研究では、子音と母音の組み合わせが記憶と音韻認識に影響を与えることが示されています。子音と母音の交互パターンは、人間の音韻処理能力に適合しています。 – The relation between discriminability and memory for vowels, consonants, and silent-center vowels | Memory & Cognition
  2. Math.random()は暗号学的に安全ではないため、セキュリティが重要な用途では使用すべきではありません。より安全な用途にはCrypto.getRandomValues()を推奨します。 – Math.random() – JavaScript | MDN
  3. HTML5のrange input要素は、数値の範囲選択に適したスライダーコントロールを提供します。正確な値よりも範囲内での相対的な選択が重要な場合に使用されます。 – <input type=”range”> – HTML | MDN
  4. FlexboxはCSS3で導入された一次元レイアウトシステムで、アイテムの配置と整列を効率的に行えます。レスポンシブデザインにおいて特に有効です。 – Basic concepts of flexbox – CSS | MDN