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