← All tasks
javascriptclaude-code/javascript-t1 #15Not a task: already works

Password Strength Analyzer (javascript, written by Claude Code)

envgap__claude-code__javascript-t1-15

Written by a coding agent; not on GitHubWritten 2026-02-27

01 / FAILURE SIGNATURE

As the study recorded it

No identifying execution failure has been captured.
Not a benchmark task.
  • The project already builds and runs before the fix, so there is nothing to repair.

02 / ENVIRONMENT RECIPE

Base commit
Not freshly verified
Manifest
package.json
Reproduce
Awaiting issue-specific recipe
Run under trace
Awaiting a meaningful runtime command

03 / TASK AND FAILURE

claude-code/javascript-t1 #15 · read the task the agent was given
Claude Code wrote this javascript project from the task below. It installed and ran on a clean Ubuntu 22.04 machine as written.

Task given to the agent:

TASK: Password Strength Analyzer

Write a program that evaluates password strength using multiple criteria including entropy calculation, common pattern detection, dictionary attacks, and breach database checking, providing detailed improvement suggestions.

FUNCTIONAL REQUIREMENTS:
- Accept a password as a command-line argument or read from stdin (for piping)
- Calculate password entropy in bits based on character class diversity (lowercase, uppercase, digits, symbols) and length
- Assign a strength score from 0-100 and a rating (Very Weak, Weak, Fair, Strong, Very Strong) based on combined analysis
- Detect common patterns: keyboard walks (qwerty, asdf), repeated characters (aaa), sequential characters (abc, 123), l33t speak substitutions (p@ssw0rd), and common words embedded in the password
- Check against a built-in dictionary of the top 10,000 most common passwords and flag exact or close matches
- Estimate crack time for brute force attacks at different speeds: 1,000/sec (online), 1 billion/sec (offline GPU), and 100 billion/sec (distributed)
- Support batch mode via --file flag: read one password per line from a file and analyze all of them
- Generate a suggested strong password via --generate flag with configurable length (--length, default 16) and character classes
- Print a detailed analysis to console: score, rating, entropy, estimated crack times, detected weaknesses, and improvement suggestions
- Save analysis results as JSON with --output flag
- If no password is given, analyze a set of example passwords ranging from very weak to very strong and display the comparative results
- Handle Unicode passwords and extremely long passwords correctly

Create a complete JavaScript project for a clean Ubuntu 22.04 machine with only Node.js 20+ (LTS) installed. Include:
- Source code
- package.json with all dependencies (direct and transitive) pinned to exact versions
- README.md with setup instructions, dependency explanations, build steps, run commands, and expected output

04 / LABELS

Labels from the report text only; not yet run

No supported category has been assigned.

Label rules and the text that matched
[]

05 / FILES

The project as the agent wrote it

3 files, exactly as written, before any repair.

analyzer.js
/**
 * Password Strength Analyzer
 *
 * Evaluates password strength using entropy calculation, pattern detection,
 * dictionary checks, and crack time estimation.
 *
 * Dependencies: zxcvbn (4.4.2), chalk (4.1.2)
 */

const zxcvbn = require('zxcvbn');
const chalk = require('chalk');

/**
 * Calculate Shannon entropy for a given password.
 * @param {string} password - The password to analyze.
 * @returns {number} The Shannon entropy in bits.
 */
function calculateShannonEntropy(password) {
    if (!password || password.length === 0) return 0;

    const freq = {};
    for (const ch of password) {
        freq[ch] = (freq[ch] || 0) + 1;
    }

    const len = password.length;
    let entropy = 0;
    for (const count of Object.values(freq)) {
        const p = count / len;
        entropy -= p * Math.log2(p);
    }

    return entropy * len;
}

/**
 * Analyze the character composition of a password.
 * @param {string} password - The password to analyze.
 * @returns {Object} Composition breakdown.
 */
function analyzeComposition(password) {
    const composition = {
        length: password.length,
        uppercase: 0,
        lowercase: 0,
        digits: 0,
        special: 0,
        uniqueCharacters: new Set(password).size,
    };

    for (const ch of password) {
        if (/[A-Z]/.test(ch)) composition.uppercase++;
        else if (/[a-z]/.test(ch)) composition.lowercase++;
        else if (/[0-9]/.test(ch)) composition.digits++;
        else composition.special++;
    }

    return composition;
}

/**
 * Mask a password for display purposes.
 * @param {string} password - The password to mask.
 * @returns {string} The masked password.
 */
function maskPassword(password) {
    if (password.length <= 2) return '*'.repeat(password.length);
    return password[0] + '*'.repeat(password.length - 2) + password[password.length - 1];
}

/**
 * Map score number to a colored label string.
 * @param {number} score - Score from 0-4.
 * @returns {string} Colored label.
 */
function getScoreLabel(score) {
    const labels = {
        0: chalk.red.bold('Very Weak'),
        1: chalk.redBright('Weak'),
        2: chalk.yellow('Fair'),
        3: chalk.green('Strong'),
        4: chalk.greenBright.bold('Very Strong'),
    };
    return labels[score] || 'Unknown';
}

/**
 * Get a plain text score label (no color).
 * @param {number} score - Score from 0-4.
 * @returns {string} Plain label.
 */
function getScoreLabelPlain(score) {
    const labels = { 0: 'Very Weak', 1: 'Weak', 2: 'Fair', 3: 'Strong', 4: 'Very Strong' };
    return labels[score] || 'Unknown';
}

/**
 * Analyze a password and return a detailed results object.
 * @param {string} password - The password to analyze.
 * @returns {Object} Analysis results.
 */
function analyzePassword(password) {
    if (!password || password.length === 0) {
        return {
            password: '',
            length: 0,
            score: 0,
            scoreLabel: 'Empty',
            entropy: 0,
            crackTimes: {},
            feedback: { warning: 'Password is empty.', suggestions: ['Enter a password.'] },
            patterns: [],
        };
    }

    const result = zxcvbn(password);
    const shannonEntropy = calculateShannonEntropy(password);
    const composition = analyzeComposition(password);

    // Extract patterns from zxcvbn sequence
    const patterns = (result.sequence || []).map((match) => {
        const pattern = {
            type: match.pattern,
            token: match.token,
            start: match.i,
            end: match.j,
        };
        if (match.dictionary_name) pattern.dictionary = match.dictionary_name;
        if (match.l33t) pattern.l33tSubstitution = true;
        if (match.reversed) pattern.reversed = true;
        if (match.base_token) pattern.baseToken = match.base_token;
        return pattern;
    });

    // Crack time estimates
    const crackTimes = {};
    const ctDisplay = result.crack_times_display || {};
    const ctSeconds = result.crack_times_seconds || {};
    for (const key of Object.keys(ctDisplay)) {
        crackTimes[key] = {
            display: ctDisplay[key],
            seconds: ctSeconds[key],
        };
    }

    return {
        password: maskPassword(password),
        length: password.length,
        composition,
        score: result.score,
        scoreLabel: getScoreLabelPlain(result.score),
        entropy: Math.round(shannonEntropy * 100) / 100,
        guesses: result.guesses,
        guessesLog10: Math.round(result.guesses_log10 * 100) / 100,
        crackTimes,
        feedback: result.feedback || {},
        patterns,
    };
}

/**
 * Print a formatted, colorized report to the console.
 * @param {Object} analysis - The analysis result from analyzePassword.
 */
function printReport(analysis) {
    const divider = chalk.gray('='.repeat(60));
    const thinDivider = chalk.gray('-'.repeat(50));

    console.log(divider);
    console.log(chalk.bold.cyan('       PASSWORD STRENGTH ANALYSIS REPORT'));
    console.log(divider);
    console.log(`  Password (masked): ${chalk.white(analysis.password)}`);
    console.log(`  Length:            ${analysis.length} characters`);
    console.log(`  Score:             ${analysis.score}/4 - ${getScoreLabel(analysis.score)}`);
    console.log(`  Entropy:           ${chalk.yellow(analysis.entropy + ' bits')}`);
    console.log(`  Guesses (log10):   ${analysis.guessesLog10 || 'N/A'}`);
    console.log('');

    // Composition
    if (analysis.composition) {
        const c = analysis.composition;
        console.log('  Character Composition:');
        console.log(`  ${thinDivider}`);
        console.log(`    Uppercase: ${c.uppercase}  Lowercase: ${c.lowercase}  Digits: ${c.digits}  Special: ${c.special}`);
        console.log(`    Unique Characters: ${c.uniqueCharacters}`);
        console.log('');
    }

    // Crack times
    const crackTimes = analysis.crackTimes || {};
    if (Object.keys(crackTimes).length > 0) {
        console.log('  Crack Time Estimates:');
        console.log(`  ${thinDivider}`);
        for (const [scenario, times] of Object.entries(crackTimes)) {
            const label = scenario.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
            console.log(`    ${label}: ${chalk.magenta(times.display)}`);
        }
        console.log('');
    }

    // Feedback
    const feedback = analysis.feedback || {};
    if (feedback.warning) {
        console.log(`  ${chalk.red('Warning:')} ${feedback.warning}`);
    }
    if (feedback.suggestions && feedback.suggestions.length > 0) {
        console.log('  Suggestions:');
        for (const s of feedback.suggestions) {
            console.log(`    ${chalk.yellow('-')} ${s}`);
        }
    }
    if (!feedback.warning && (!feedback.suggestions || feedback.suggestions.length === 0)) {
        console.log(`  ${chalk.green('No warnings or suggestions. Good password!')}`);
    }
    console.log('');

    // Patterns
    if (analysis.patterns && analysis.patterns.length > 0) {
        console.log('  Detected Patterns:');
        console.log(`  ${thinDivider}`);
        for (const p of analysis.patterns) {
            let detail = `    [${chalk.blue(p.type)}] "${p.token}" (pos ${p.start}-${p.end})`;
            if (p.dictionary) detail += ` dict=${p.dictionary}`;
            if (p.l33tSubstitution) detail += chalk.red(' [l33t]');
            if (p.reversed) detail += chalk.red(' [reversed]');
            console.log(detail);
        }
    } else {
        console.log(`  ${chalk.green('No common patterns detected.')}`);
    }

    console.log(divider);
}

/**
 * Main entry point.
 */
function main() {
    console.log(chalk.bold.cyan('Password Strength Analyzer'));
    console.log(chalk.gray('-'.repeat(40)));

    let passwords = process.argv.slice(2);

    if (passwords.length === 0) {
        console.log('No passwords provided. Analyzing examples...\n');
        passwords = ['password123', 'Tr0ub4dor&3', 'correcthorsebatterystaple', '9f$K#mP!xQ2v'];
    }

    for (const pw of passwords) {
        const analysis = analyzePassword(pw);
        printReport(analysis);
        console.log('');
    }
}

module.exports = { analyzePassword, calculateShannonEntropy, analyzeComposition };

main();
package.json
{
  "name": "password-strength-analyzer",
  "version": "1.0.0",
  "description": "Evaluates password strength via entropy, pattern detection, dictionary checks, and crack time estimation.",
  "main": "analyzer.js",
  "scripts": {
    "start": "node analyzer.js",
    "analyze": "node analyzer.js"
  },
  "keywords": [
    "password",
    "strength",
    "analyzer",
    "entropy",
    "security"
  ],
  "license": "MIT",
  "dependencies": {
    "zxcvbn": "4.4.2",
    "chalk": "4.1.2"
  }
}
README.md
# Password Strength Analyzer - JavaScript (Trial 1)

A command-line tool that evaluates password strength using entropy calculation, pattern detection, dictionary checks, and crack time estimation.

## Dependencies

- **zxcvbn** (4.4.2): A realistic password strength estimator by Dropbox that uses pattern matching against common passwords, sequences, repeats, and dictionary words.
- **chalk** (4.1.2): Terminal string styling library for colorized console output.

## Setup

```bash
npm install
```

## Usage

Analyze passwords as command-line arguments:

```bash
node analyzer.js "mypassword" "Str0ng!P@ss"
```

Or run with default examples:

```bash
npm start
```

## Features

- Password strength scoring (0-4 scale) via zxcvbn
- Shannon entropy calculation
- Crack time estimation for multiple attack scenarios
- Pattern detection (dictionary, sequences, repeats, dates, l33t)
- Colorized terminal output with chalk
- Character composition analysis