How can I randomly capitalise letters in a string - javascript

I'm sorry if this has been asked before, but I can't seem to find the right answer.
I'm trying to create a random password generator using Javascript. I've set meself 4 basic requirements:
Must contain letters, numbers and special characters
Must be 14 characters
Must have upper and lower case lettering
Must log the result as a string
Here is what I have:
var characters = 'abcdefghijklmnoqrstuvwxyz0123456789?<>!"£$%^&*()-+./';
var results = '';
var length = characters.length;
function randomPassword() {
for (i=0; i<=13; i++) {
var mix = characters.charAt(Math.floor(Math.random() * length));
var newString = results += mix;
}
console.log(newString);
}
randomPassword();
The code above passes all of my requirements apart from the upper and lower case letters. Is there a way to randomly capitalise some of the letters in my string? I've tried playing with .toUpperCase() in the same way I have to create my 'mix' variable, but I can't work out how to do it.
This isn't for any real life projects. I'm just using this as a way to try to learn Javascript, so any advice would be greatly appreciated :)
Thanks!

Here's one way
myString.toLowerCase().split('').map(function(c){
return Math.random() < .5? c : c.toUpperCase();
}).join('');

your code is good and correct just make a simple improvement as mentioned below. you can achieve your goal.
var characters = 'abcdefghijklmnoqrstuvwxyz0123456789?<>!"£$%^&*()-+./';
var results = '';
var length = characters.length;
function randomPassword() {
var check = 2;
for (i=0; i<=13; i++) {
var mix = characters.charAt(Math.floor(Math.random() * length));
if (mix.match(/[a-z]/i) && check>0) {
mix = mix.toUpperCase();
check --;
}
var newString = results += mix;
}
console.log(newString);
}
randomPassword();
var characters = 'abcdefghijklmnoqrstuvwxyz0123456789?<>!"£$%^&*()-+./';
var results = '';
var length = characters.length;
function randomPassword() {
var check = 2;
for (i=0; i<=13; i++) {
var mix = characters.charAt(Math.floor(Math.random() * length));
if (mix.match(/[a-z]/i) && check>0) {
mix = mix.toUpperCase();
check --;
}
var newString = results += mix;
}
console.log(newString);
}
randomPassword();

if you need to have both upper and lower characters and numbers and special chars, a random choice from a single characters variable can't always ensure this requirement.
In the version below I've created an array of characters subsets, where every required subset is included at least 3 times in the final password.
Simple version
var alphabet = [
'abcdefghijklmnoqrstuvwxyz',
'ABCDEFGHIJKLMNOQRSTUVWXYZ',
'0123456789',
'?<>!"£$%^&*()-+./'
];
password = '';
for (var i = 0; i < 14; i++) {
var subset = alphabet[i%4];
password += subset[Math.floor(Math.random() * subset.length)]
}
console.log(password);
Safer version
here both the subsets and the password are scrambled using a JS implementation of Fisher-Yates algorithm so to avoid predictable generations.
function shuffle_Fisher_Yates(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
var alphabet = shuffle_Fisher_Yates([
'abcdefghijklmnoqrstuvwxyz',
'ABCDEFGHIJKLMNOQRSTUVWXYZ',
'0123456789',
'?<>!"£$%^&*()-+./'
]);
password = '';
for (var i = 0; i < 14; i++) {
var subset = alphabet[i%4];
password += subset[Math.floor(Math.random() * subset.length)]
}
console.log(shuffle_Fisher_Yates(password.split('')).join(''));

It's my way to capitalise some random characters from a given string.
const myString = 'manoj_rana';
const randomCapitaliseString = [...myString].map(c => Math.random() < .6 ? c : c.toUpperCase()).join('');

Related

Why does this embedded function not work (inside of a javascript algorithm), and thereby preventing the javascript algorithm from being solved?

Question
Find the longest substring in alphabetical order.
Example: the longest alphabetical substring in "asdfaaaabbbbcttavvfffffdf" is "aaaabbbbctt".
There are tests with strings up to 10 000 characters long so your code will need to be efficient.
The input will only consist of lowercase characters and will be at least one letter long.
If there are multiple solutions, return the one that appears first.
My Solution
function longest(str) {
//first element of count == total count of the highest number
//second element of count == longest str so far
let count = [0, ''];
//temp count == length of current str
let tempCount = [0];
//split the str to an array
let strArr = str.split('');
//loop through each letter of the string
for(let i = 0; i < strArr.length; i++){
//if the character is higher in the alpahabet than the last then
if(convertToNumber(strArr[i])<convertToNumber((strArr[i]-1)) || convertToNumber((strArr[i]-1))== undefined){
tempCount[0]++;
//if the current character is not higher than the last
} else {
if(tempCount[0] > count[0]){
//change the longest str number to the length of this str
count[0] = tempCount[0];
//slice the new longest str
let longestStr = strArr.slice(strArr[i]-tempCount[0], strArr[i]);
//join the str together
count[1] = longestStr.join('');
//reset the temp count
tempCount[0] = 0;
} else {
//reset the temp count
tempCount[0] = 0;
}
}
}
//converts the relevant letter to a code
function convertToNumber(letter){
return letter.charCodeAt(0);
}
//returns the longest str
return count[1];
}
console.log(longest('asdfaaaabbbbcttavvfffffdf'));
The algorithm returns 'letter.charCodeAt is not a function'
Why is this the case and how can I make adjustments to fix the algorithm?
The problem is in here:
if(convertToNumber(strArr[i])<convertToNumber((strArr[i]-1)) || convertToNumber((strArr[i]-1))== undefined)
you are trying to subtract 1(Number) from a letter(String). It should be strArr[i-1].
But also
even after fixing it you'd still get an error for:
convertToNumber(strArr[i]) < convertToNumber(strArr[i-1])
if i will be zero as strArr[-1] will give undefined.
const arr = [1, 2, 3];
console.log(arr[-1]);
Is basically undefined.charCodeAt(0);, which will produce error.
I know that the OP wants a solution for his error. fedsec showed him for this a way. So I think there is nothing else to do.
I just put here my solution of the task, so the OP can compare to other possible solutions.
function longest(str) {
let max = 1;
let maxStr = str.charAt(0);
let char = maxStr;
let testStr = maxStr;
let count = 1;
for (i=1; i<=str.length; i++) {
let prev = char;
char = str.charAt(i);
if (prev <= char) {
count++;
testStr += char;
if (count>max) {
max = count;
maxStr = testStr;
}
} else {
if ( i+count >str.length) break;
count = 1;
testStr = char;
}
}
return(maxStr);
}
console.log(longest('asdfaaaabbbbcttavvfffffdf'));

Generate random string with capital letters and numbers without O and 0

I'm wanting to generate a random string with a length of 12 with capital letters only and numbers with no letter O or the number 0 in javascript. here is what I have:
Math.random().toString(36).substr(2, 12)
but the problem is that it is not all capital and i don't want the letter O or the number 0. thanks
function rand_str_without_O0() {
const list = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789";
var res = "";
for(var i = 0; i < 12; i++) {
var rnd = Math.floor(Math.random() * list.length);
res = res + list.charAt(rnd);
}
return res;
}
Usage:
var randomString = rand_str_without_O0();
let foo = function(length) { //length should be <= 7
return Math.random().toString(36).toUpperCase().replace(/[0-9O]/g, '').substring(1,length+1)
}
response = foo(6) + foo(6)
This will first generate random string convert to uppercase, then remove the un-needed values and then create substring of required length. As far as I have seen, this will generate a string of at-least 7 characters so you can use it twice to generate string of length 12.
This is a quick solution and probably not optimal.
var myString = function(len, excluded) {
var included = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
// remove the excluded chars from the included string
for (var i = 0; i < excluded.length; i++) {
included = included.split(excluded[i]).join('');
}
// add len random chars form whatever is left.
var output = '';
for (var i = 0; i < len; i++) {
output += included.charAt(Math.random() * included.length);
}
return output;
}
And you call it with the desired length and an array of characters to exclude:
console.log(myString(12, ['0', 'O']));
EDIT: This solution allows the output length and the chars to be excluded to be passed on as parameters.
var all_chars_without_O0 = 'ABCDEFGHIJKLMNPQRSTUVWXYZ123456789'.split('');
// Returns a random integer between min (included) and max (excluded)
// Using Math.round() will give you a non-uniform distribution!
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
function pickRandom(arr) {
return arr[getRandomInt(0, arr.length)];
}
function randomString(length = 12, chars = all_chars_without_O0) {
var s = '';
while (length--)
s += pickRandom(chars);
return s;
}
https://jsfiddle.net/MrQubo/fusb1746/1/
Or using lodash:
var all_chars_without_O0 = 'ABCDEFGHIJKLMNPQRSTUVWXYZ123456789'.split('');
function randomString(length = 12, chars = all_chars_without_O0) {
return _.sampleSize(chars, length).join('');
}
However, you should be warned, that Math.random() doesn't provide cryptographically secure random numbers. See Math.random() for more information.

Random 'email format' text using jQuery

I want to know how I can get a random text variable in jQuery like this format:
gwtq3tw3232dsk#domain.com
15 digit random combination of letters and numbers in the first part and '#domain.com' in the second part which remains the same.
I want to get real random entries that are different all the time.
how to do this with javascript or jquery?
Thanks
Use chancejs github
email
chance.email()
chance.email({domain: "example.com"})
Return a random email with a random domain.
chance.email()
=> 'kawip#piklojzob.gov'
Optionally specify a domain and the email will be random but the domain will not.
chance.email({domain: 'example.com')
=> 'giigjom#example.com'
Or pure JavaScript
fiddle DEMO
function makeEmail() {
var strValues = "abcdefg12345";
var strEmail = "";
var strTmp;
for (var i = 0; i < 10; i++) {
strTmp = strValues.charAt(Math.round(strValues.length * Math.random()));
strEmail = strEmail + strTmp;
}
strTmp = "";
strEmail = strEmail + "#";
for (var j = 0; j < 8; j++) {
strTmp = strValues.charAt(Math.round(strValues.length * Math.random()));
strEmail = strEmail + strTmp;
}
strEmail = strEmail + ".com"
return strEmail;
}
console.log(makeEmail());
var chars = 'abcdefghijklmnopqrstuvwxyz1234567890';
var string = '';
for(var ii=0; ii<15; ii++){
string += chars[Math.floor(Math.random() * chars.length)];
}
alert(string + '#domain.com');
This will randomly pick characters to add to the email string.
Note that this might, once in a blue moon, generate duplicates. In order to completely eliminate duplicates, you would have to store all generated strings and check to make sure that the one you are generating is unique.
JSFiddle Demo.
Using the answers from generate a string of 5 random characters
function getRandomEmail(domain,length)
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < length; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text + domain;
}
var email = getRandomEmail("#domain.com",15);
Lets do the trick with toSting to generate alphanumeric string
return Math.random().toString(36).substring(2,11) + '#domain.com';
shortest as possible
If you like to have first character a letter, it could be combination with selection of the first character from the character list
var chars = 'abcdefghijklmnopqrstuvwxyz';
return chars[Math.floor(Math.random()*26)] + Math.random().toString(36).substring(2,11) + '#domain.com';

Generate random letters in javascript and count how many times each letter has occurred?

I want to generate a string of random letters say 10 letters from a-z one after the other i.e. the next letter should be displayed after the previous letter after a certain delay, later, I want to calculate the number of times each letter has been generated, unlike what I have done previously, i.e. I have taken a predefined array of letters and generated them accordingly.
Shorter way to generate such a string using String.fromCharCode:
for (var i = 0, letter; i < 10; i++) {
setTimeout(function() {
letter = String.fromCharCode(97 + Math.floor(Math.random() * 26));
out.appendChild(document.createTextNode(letter)); // append somewhere
}, 2000 * i);
}
And complete demo covering all the problems in this question: http://jsfiddle.net/p8Pjq/
Use the setInterval method to run code at an interval. Set up an array for counting each character from the start, then you can count them when you create them instead of afterwards:
var text = '';
var chars = 'abcdefghijklmnopqrstuvwxyz';
var cnt = new Array(chars.length);
for (var i = 0; i < cnt.length; i++) cnt[i] = 0;
var handle = window.setInterval(function(){
var ch = Math.floor(Math.random() * chars.length);
cnt[ch]++;
text += chars.charAt(ch);
$('#display').text(text);
if (text.length == 20) {
window.clearInterval(handle);
// now all characrers are created and counted
}
}, 2000);
Demo: http://jsfiddle.net/R8rDH/
I am stealing this answer, but look here: Generate random string/characters in JavaScript
function makeid()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}

JavaScript strings outside of the BMP

BMP being Basic Multilingual Plane
According to JavaScript: the Good Parts:
JavaScript was built at a time when Unicode was a 16-bit character set, so all characters in JavaScript are 16 bits wide.
This leads me to believe that JavaScript uses UCS-2 (not UTF-16!) and can only handle characters up to U+FFFF.
Further investigation confirms this:
> String.fromCharCode(0x20001);
The fromCharCode method seems to only use the lowest 16 bits when returning the Unicode character. Trying to get U+20001 (CJK unified ideograph 20001) instead returns U+0001.
Question: is it at all possible to handle post-BMP characters in JavaScript?
2011-07-31: slide twelve from Unicode Support Shootout: The Good, The Bad, & the (mostly) Ugly covers issues related to this quite well:
Depends what you mean by ‘support’. You can certainly put non-UCS-2 characters in a JS string using surrogates, and browsers will display them if they can.
But, each item in a JS string is a separate UTF-16 code unit. There is no language-level support for handling full characters: all the standard String members (length, split, slice etc) all deal with code units not characters, so will quite happily split surrogate pairs or hold invalid surrogate sequences.
If you want surrogate-aware methods, I'm afraid you're going to have to start writing them yourself! For example:
String.prototype.getCodePointLength= function() {
return this.length-this.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g).length+1;
};
String.fromCodePoint= function() {
var chars= Array.prototype.slice.call(arguments);
for (var i= chars.length; i-->0;) {
var n = chars[i]-0x10000;
if (n>=0)
chars.splice(i, 1, 0xD800+(n>>10), 0xDC00+(n&0x3FF));
}
return String.fromCharCode.apply(null, chars);
};
I came to the same conclusion as bobince. If you want to work with strings containing unicode characters outside of the BMP, you have to reimplement javascript's String methods. This is because javascript counts characters as each 16-bit code value. Symbols outside of the BMP need two code values to be represented. You therefore run into a case where some symbols count as two characters and some count only as one.
I've reimplemented the following methods to treat each unicode code point as a single character: .length, .charCodeAt, .fromCharCode, .charAt, .indexOf, .lastIndexOf, .splice, and .split.
You can check it out on jsfiddle: http://jsfiddle.net/Y89Du/
Here's the code without comments. I tested it, but it may still have errors. Comments are welcome.
if (!String.prototype.ucLength) {
String.prototype.ucLength = function() {
// this solution was taken from
// http://stackoverflow.com/questions/3744721/javascript-strings-outside-of-the-bmp
return this.length - this.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g).length + 1;
};
}
if (!String.prototype.codePointAt) {
String.prototype.codePointAt = function (ucPos) {
if (isNaN(ucPos)){
ucPos = 0;
}
var str = String(this);
var codePoint = null;
var pairFound = false;
var ucIndex = -1;
var i = 0;
while (i < str.length){
ucIndex += 1;
var code = str.charCodeAt(i);
var next = str.charCodeAt(i + 1);
pairFound = (0xD800 <= code && code <= 0xDBFF && 0xDC00 <= next && next <= 0xDFFF);
if (ucIndex == ucPos){
codePoint = pairFound ? ((code - 0xD800) * 0x400) + (next - 0xDC00) + 0x10000 : code;
break;
} else{
i += pairFound ? 2 : 1;
}
}
return codePoint;
};
}
if (!String.fromCodePoint) {
String.fromCodePoint = function () {
var strChars = [], codePoint, offset, codeValues, i;
for (i = 0; i < arguments.length; ++i) {
codePoint = arguments[i];
offset = codePoint - 0x10000;
if (codePoint > 0xFFFF){
codeValues = [0xD800 + (offset >> 10), 0xDC00 + (offset & 0x3FF)];
} else{
codeValues = [codePoint];
}
strChars.push(String.fromCharCode.apply(null, codeValues));
}
return strChars.join("");
};
}
if (!String.prototype.ucCharAt) {
String.prototype.ucCharAt = function (ucIndex) {
var str = String(this);
var codePoint = str.codePointAt(ucIndex);
var ucChar = String.fromCodePoint(codePoint);
return ucChar;
};
}
if (!String.prototype.ucIndexOf) {
String.prototype.ucIndexOf = function (searchStr, ucStart) {
if (isNaN(ucStart)){
ucStart = 0;
}
if (ucStart < 0){
ucStart = 0;
}
var str = String(this);
var strUCLength = str.ucLength();
searchStr = String(searchStr);
var ucSearchLength = searchStr.ucLength();
var i = ucStart;
while (i < strUCLength){
var ucSlice = str.ucSlice(i,i+ucSearchLength);
if (ucSlice == searchStr){
return i;
}
i++;
}
return -1;
};
}
if (!String.prototype.ucLastIndexOf) {
String.prototype.ucLastIndexOf = function (searchStr, ucStart) {
var str = String(this);
var strUCLength = str.ucLength();
if (isNaN(ucStart)){
ucStart = strUCLength - 1;
}
if (ucStart >= strUCLength){
ucStart = strUCLength - 1;
}
searchStr = String(searchStr);
var ucSearchLength = searchStr.ucLength();
var i = ucStart;
while (i >= 0){
var ucSlice = str.ucSlice(i,i+ucSearchLength);
if (ucSlice == searchStr){
return i;
}
i--;
}
return -1;
};
}
if (!String.prototype.ucSlice) {
String.prototype.ucSlice = function (ucStart, ucStop) {
var str = String(this);
var strUCLength = str.ucLength();
if (isNaN(ucStart)){
ucStart = 0;
}
if (ucStart < 0){
ucStart = strUCLength + ucStart;
if (ucStart < 0){ ucStart = 0;}
}
if (typeof(ucStop) == 'undefined'){
ucStop = strUCLength - 1;
}
if (ucStop < 0){
ucStop = strUCLength + ucStop;
if (ucStop < 0){ ucStop = 0;}
}
var ucChars = [];
var i = ucStart;
while (i < ucStop){
ucChars.push(str.ucCharAt(i));
i++;
}
return ucChars.join("");
};
}
if (!String.prototype.ucSplit) {
String.prototype.ucSplit = function (delimeter, limit) {
var str = String(this);
var strUCLength = str.ucLength();
var ucChars = [];
if (delimeter == ''){
for (var i = 0; i < strUCLength; i++){
ucChars.push(str.ucCharAt(i));
}
ucChars = ucChars.slice(0, 0 + limit);
} else{
ucChars = str.split(delimeter, limit);
}
return ucChars;
};
}
More recent JavaScript engines have String.fromCodePoint.
const ideograph = String.fromCodePoint( 0x20001 ); // outside the BMP
Also a code-point iterator, which gets you the code-point length.
function countCodePoints( str )
{
const i = str[Symbol.iterator]();
let count = 0;
while( !i.next().done ) ++count;
return count;
}
console.log( ideograph.length ); // gives '2'
console.log( countCodePoints(ideograph) ); // '1'
Yes, you can. Although support to non-BMP characters directly in source documents is optional according to the ECMAScript standard, modern browsers let you use them. Naturally, the document encoding must be properly declared, and for most practical purposes you would need to use the UTF-8 encoding. Moreover, you need an editor that can handle UTF-8, and you need some input method(s); see e.g. my Full Unicode Input utility.
Using suitable tools and settings, you can write var foo = '𠀁'.
The non-BMP characters will be internally represented as surrogate pairs, so each non-BMP character counts as 2 in the string length.
Using for (c of this) instruction, one can make various computations on a string that contains non-BMP characters. For instance, to compute the string length, and to get the nth character of the string:
String.prototype.magicLength = function()
{
var c, k;
k = 0;
for (c of this) // iterate each char of this
{
k++;
}
return k;
}
String.prototype.magicCharAt = function(n)
{
var c, k;
k = 0;
for (c of this) // iterate each char of this
{
if (k == n) return c + "";
k++;
}
return "";
}
This old topic has now a simple solution in ES6:
Split characters into an array
simple version
[..."😴😄😃⛔🎠🚓🚇"] // ["😴", "😄", "😃", "⛔", "🎠", "🚓", "🚇"]
Then having each one separated you can handle them easily for most common cases.
Credit: DownGoat
Full solution
To overcome special emojis as the one in the comment, one can search for the connection charecter (char code 8205 in UTF-16) and make some modifications. Here is how:
let myStr = "👩‍👩‍👧‍👧😃𝌆"
let arr = [...myStr]
for (i = arr.length-1; i--; i>= 0) {
if (arr[i].charCodeAt(0) == 8205) { // special combination character
arr[i-1] += arr[i] + arr[i+1]; // combine them back to a single emoji
arr.splice(i, 2)
}
}
console.log(arr.length) //3
Haven't found a case where this doesn't work. Comment if you do.
To conclude
it seems that JS uses the 8205 char code to represent UCS-2 characters as a UTF-16 combinations.

Categories

Resources