Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save VenkataRaju/a23678e94060f2b1749555d915846d11 to your computer and use it in GitHub Desktop.
Save VenkataRaju/a23678e94060f2b1749555d915846d11 to your computer and use it in GitHub Desktop.
Finds Invalid Special Characters In Password
<!-- 21 Aug 2018 -->
<html>
<head lang='en-US' >
<meta charset='UTF-8' />
<meta content='text/html; charset=UTF-8' http-equiv='content-type' />
<title>Find Invalid Special Characters In Password</title>
<script>
function $(id) { return document.getElementById(id); }
function init()
{
let allSpecialChars, considerValidSpecialChars, validOrInvalidSpecialChars, maxNoOfCharsPerRow;
let showCharactersChoice;
let invalidCharsTablesDiv = $('invalid-chars-tbls');
let invalidCharsTables = invalidCharsTablesDiv.children;
let templateTbl = invalidCharsTables[0];
templateTbl.remove();
let passwordTf = $('password');
let validate = () =>
{
let password = passwordTf.value;
if (!password)
{
clearRemainingElements(invalidCharsTables, 0);
return;
}
let row0, row1;
let cells0, cells1;
let cellNo = 0, tableNo = 0, charNo = 0;
for (let c of password)
{
if (cellNo % maxNoOfCharsPerRow === 0)
{
if (cells0)
clearRemainingElementsForMultipleEls(cellNo, cells0, cells1);
let table = invalidCharsTables[tableNo++];
if (!table)
{
table = templateTbl.cloneNode(true);
table.title = 'Click to position the cursor at this character in Password';
invalidCharsTablesDiv.append(table);
table.addEventListener('click', e =>
{
let el = e.target;
if (el.tagName !== 'TD')
return;
let tr = el.parentNode;
let prevTr = tr.previousElementSibling;
if (prevTr)
{
let i = [...tr.children].indexOf(el);
el = prevTr.children[i];
}
let i = el.textContent - 1;
placeCursorAtThePosition(passwordTf, i);
});
}
[row0, row1] = table.rows;
let display = showCharacterNumberCb.checked ? 'table-row' : 'none';
row0.style.display = display;
[cells0, cells1] = [row0.cells, row1.cells];
cellNo = 0;
}
let cell0 = cells0[cellNo];
let cell1 = cells1[cellNo];
if (!cell0)
{
cell0 = row0.insertCell();
cell1 = row1.insertCell();
}
let isValid;
if (validOrInvalidSpecialChars.has(c))
isValid = considerValidSpecialChars;
else if (!allSpecialChars.has(c))
isValid = true;
else
isValid = !considerValidSpecialChars;
if (isValid)
{
cell0.classList.remove('error');
cell1.classList.remove('error');
}
else
{
cell0.classList.add('error');
cell1.classList.add('error');
}
cell0.textContent = ++charNo;
cellNo++;
if (showCharactersChoice === 'show-only-invalid-characters')
cell1.textContent = isValid ? '*' : c;
else if (showCharactersChoice === 'show-all-characters')
cell1.textContent = c;
else if (showCharactersChoice === 'mask-all-characters')
cell1.textContent = '*';
else
throw new Error(`Invalid choice '${showCharactersChoice}'`);
}
clearRemainingElementsForMultipleEls(cellNo, cells0, cells1);
clearRemainingElements(invalidCharsTables, tableNo);
};
function clearRemainingElementsForMultipleEls(index, ...els)
{
for (let el of els)
clearRemainingElements(el, index);
}
callAndAddSlowListener($('all-special-chars'), 'input', el => { allSpecialChars = new Set(el.value); }, validate);
{
let el = document.querySelector('input[type=radio][name=valid-or-invalid-special-chars-radio]');
let action = () =>
{
considerValidSpecialChars = el.checked;
validate();
};
el.parentNode.parentNode.addEventListener('click', e =>
{
let el = e.target;
if (el.tagName === 'INPUT')
action();
});
action();
}
callAndAddSlowListener($('valid-or-invalid-special-chars-tf'), 'input', el => { validOrInvalidSpecialChars = new Set(el.value); }, validate);
{
let el = $('max-chars-per-row');
let action = () =>
{
let value = +el.value;
maxNoOfCharsPerRow = (isNaN(value) || value < 1) ? 20 : value;
validate();
};
slowListener(el, 'input', action);
action();
}
let settingsTd = $('show-characters-settings');
let showCharacterNumberCb = settingsTd.querySelector('input[type=checkbox]');
let showOrHideNumberRows = () =>
{
let display = showCharacterNumberCb.checked ? 'table-row' : 'none';
for (let table of invalidCharsTables)
table.rows[0].style.display = display;
};
let extractRadioValue = () => settingsTd.querySelector('input[name=chars-in-output]:checked').value;
showCharactersChoice = extractRadioValue();
settingsTd.addEventListener('click', e =>
{
let el = e.target;
if (el.tagName !== 'INPUT')
return;
if (el.type === 'checkbox')
showOrHideNumberRows();
else
{
showCharactersChoice = extractRadioValue();
validate();
}
});
// showOrHideNumberRows();
slowListener($('password'), 'input', validate);
}
function callAndAddSlowListener(el, eventType, update, validate, delayInMillis = 200)
{
update(el);
let combined = () => { update(el); validate(); };
slowListener(el, eventType, combined, delayInMillis);
}
function slowListener(el, eventType, action, delayInMillis)
{
let timerId;
el.addEventListener(eventType, e =>
{
clearTimeout(timerId);
timerId = setTimeout(action, delayInMillis);
});
}
function clearRemainingElements(liveEls, index)
{
for (let start = liveEls.length - 1; start >= index; liveEls[start--].remove());
}
function placeCursorAtThePosition(tf, pos)
{
tf.setSelectionRange(pos, pos);
tf.focus();
}
</script>
<style>
body {
font-family: monospace;
font-size: 1rem;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
#show-characters-settings label {
display: inline-block;
margin: 0.2em 0;
}
input[type=radio], input[type=checkbox] {
vertical-align: text-bottom;
}
#invalid-chars-tbls table {
margin: 0.5rem 0;
}
#invalid-chars-tbls td {
width: 2.5rem;
padding: 0 0.5rem;
height: 1rem;
text-align: center;
cursor: pointer;
}
#invalid-chars-tbls td:hover {
font-weight: bold;
}
.error {
color: red;
}
</style>
</head>
<body onload='init()'>
<table>
<tr><td>All special characters: </td><td><input id='all-special-chars' type='text' value='`~!@#$%^&*()-_=+[]{}\|;:&apos;",.<>/? '/></td></tr>
<tr>
<td>
<label><input name='valid-or-invalid-special-chars-radio' type='radio' checked='checked' />Valid</label>
<label><input name='valid-or-invalid-special-chars-radio' type='radio' />Invalid</label>
special characters:
</td>
<td>
<input id='valid-or-invalid-special-chars-tf' type='text' value='($#^@\&%_.~!*)' />
</td>
</tr>
<tr><td>Password: </td><td><input id='password' type='password' /></td></tr>
<tr><td>Maximum number of characters per row: </td><td><input id='max-chars-per-row' type='number' min='1' value='20' style='width: 4rem' /></td></tr>
<tr><td colspan='2'></td></tr>
<tr><td colspan='2'></td></tr>
<tr>
<td colspan='2' style='text-align: center'>
<span id='show-characters-settings' style='display: inline-block; text-align: left'>
<label><input name='char-num-in-output' type='checkbox' checked='checked' />Show character number</label><br><br>
<label><input name='chars-in-output' type='radio' value='mask-all-characters' />Mask all characters</label><br>
<label><input name='chars-in-output' type='radio' value='show-only-invalid-characters' checked='checked' />Show only invalid characters</label><br>
<label><input name='chars-in-output' type='radio' value='show-all-characters' />Show all characters</label>
</span>
</td>
</tr>
</table>
<div id='invalid-chars-tbls'>
<table border='1' style='border-collapse: collapse'><tr></tr><tr></tr></table>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment