New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

randomstring

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

randomstring - npm Package Compare versions

Comparing version 1.1.5 to 1.2.0

6

CHANGELOG.md

@@ -0,1 +1,7 @@

1.2.0 / May 10, 2021
==================
* Use randombytes instead of node.crypto to prevent biased output
* Add support for async generation
* Support for binary and octal charsets
1.1.5 / May 18, 2016

@@ -2,0 +8,0 @@ ==================

24

lib/charset.js

@@ -9,8 +9,10 @@ var arrayUniq = require('array-uniq');

var chars;
var numbers = '0123456789';
var charsLower = 'abcdefghijklmnopqrstuvwxyz';
var charsUpper = charsLower.toUpperCase();
var hexChars = 'abcdef';
var numbers = '0123456789';
var charsLower = 'abcdefghijklmnopqrstuvwxyz';
var charsUpper = charsLower.toUpperCase();
var hexChars = 'abcdef';
var binaryChars = '01';
var octalChars = '01234567';
if (type === 'alphanumeric') {

@@ -28,6 +30,12 @@ chars = numbers + charsLower + charsUpper;

}
else if (type === 'binary') {
chars = binaryChars;
}
else if (type === 'octal') {
chars = octalChars;
}
else {
chars = type;
}
this.chars = chars;

@@ -56,2 +64,2 @@ }

module.exports = exports = Charset;
module.exports = exports = Charset;
"use strict";
var crypto = require('crypto');
var randomBytes = require('randombytes');
var Charset = require('./charset.js');

@@ -9,3 +9,3 @@

try {
return crypto.randomBytes(length);
return randomBytes(length);
} catch(e) {

@@ -17,12 +17,37 @@ continue;

exports.generate = function(options) {
function processString(buf, initialString, chars, reqLen, maxByte) {
var string = initialString;
for (var i = 0; i < buf.length && string.length < reqLen; i++) {
var randomByte = buf.readUInt8(i);
if (randomByte < maxByte) {
string += chars.charAt(randomByte % chars.length);
}
}
return string;
}
function getAsyncString(string, chars, length, maxByte, cb) {
crypto.randomBytes(length, function(err, buf) {
if (err) {
// Since it is waiting for entropy, errors are legit and we shouldn't just keep retrying
cb(err);
}
var generatedString = processString(buf, string, chars, length, maxByte);
if (generatedString.length < length) {
getAsyncString(generatedString, chars, length, maxByte, cb);
} else {
cb(null, generatedString);
}
})
}
exports.generate = function(options, cb) {
var charset = new Charset();
var length, chars, capitalization, string = '';
// Handle options
if (typeof options === 'object') {
length = options.length || 32;
if (options.charset) {

@@ -34,11 +59,11 @@ charset.setType(options.charset);

}
if (options.capitalization) {
charset.setcapitalization(options.capitalization);
}
if (options.readable) {
charset.removeUnreadable();
}
charset.removeDuplicates();

@@ -54,18 +79,18 @@ }

}
// Generate the string
var charsLen = charset.chars.length;
var maxByte = 256 - (256 % charsLen);
while (length > 0) {
var buf = safeRandomBytes(Math.ceil(length * 256 / maxByte));
for (var i = 0; i < buf.length && length > 0; i++) {
var randomByte = buf.readUInt8(i);
if (randomByte < maxByte) {
string += charset.chars.charAt(randomByte % charsLen);
length--;
}
if (!cb) {
while (string.length < length) {
var buf = safeRandomBytes(Math.ceil(length * 256 / maxByte));
string = processString(buf, string, charset.chars, length, maxByte);
}
return string;
}
return string;
getAsyncString(string, charset.chars, length, maxByte, cb);
};
{
"name": "randomstring",
"version": "1.1.5",
"version": "1.2.0",
"author": "Elias Klughammer <elias@klughammer.com> (http://www.klughammer.com)",

@@ -16,3 +16,4 @@ "description": "A module for generating random strings",

"dependencies": {
"array-uniq": "1.0.2"
"array-uniq": "1.0.2",
"randombytes": "2.0.3"
},

@@ -19,0 +20,0 @@ "devDependencies": {

@@ -36,2 +36,8 @@ # node-randomstring

// >> "accbaabbbbcccbccccaacacbbcbbcbbc"
randomstring.generate({
charset: 'abc'
}, cb);
// >> "cb(generatedString) {}"
```

@@ -43,14 +49,18 @@

- `generate(options)`
- `length` - the length of the random string. (default: 32) [OPTIONAL]
- `readable` - exclude poorly readable chars: 0OIl. (default: false) [OPTIONAL]
- `charset` - define the character set for the string. (default: 'alphanumeric') [OPTIONAL]
- `alphanumeric` - [0-9 a-z A-Z]
- `alphabetic` - [a-z A-Z]
- `numeric` - [0-9]
- `hex` - [0-9 a-f]
- `custom` - any given characters
- `capitalization` - define whether the output should be lowercase / uppercase only. (default: null) [OPTIONAL]
- `lowercase`
- `uppercase`
- `generate(options, cb)`
- `options`
- `length` - the length of the random string. (default: 32) [OPTIONAL]
- `readable` - exclude poorly readable chars: 0OIl. (default: false) [OPTIONAL]
- `charset` - define the character set for the string. (default: 'alphanumeric') [OPTIONAL]
- `alphanumeric` - [0-9 a-z A-Z]
- `alphabetic` - [a-z A-Z]
- `numeric` - [0-9]
- `hex` - [0-9 a-f]
- `binary` - [01]
- `octal` - [0-7]
- `custom` - any given characters
- `capitalization` - define whether the output should be lowercase / uppercase only. (default: null) [OPTIONAL]
- `lowercase`
- `uppercase`
- `cb` - Optional. If provided uses async version of `crypto.randombytes`

@@ -66,3 +76,3 @@ ## Command Line Usage

> CpMg433
$ randomstring length=24 charset=github readable

@@ -69,0 +79,0 @@ > hthbtgiguihgbuttuutubugg

@@ -14,2 +14,9 @@ "use strict";

it("returns a string async", function(done) {
random(undefined, function(err, string) {
assert.equal(typeof(string), "string");
done();
});
});
it("defaults to 32 characters in length", function() {

@@ -22,19 +29,31 @@ assert.equal(random().length, 32);

});
it("accepts length as an option param", function() {
assert.equal(random({ length: 7 }).length, 7);
});
it("accepts 'numeric' as charset option", function() {
var testData = random({ length: testLength, charset: 'numeric' });
var search = testData.search(/\D/ig);
assert.equal(search, -1);
it("accepts length as an option param async", function(done) {
random(({ length: 7 }), function(err, string) {
assert.equal(string.length, 7);
done();
});
});
it("accepts 'numeric' as charset option async", function(done) {
random({ length: testLength, charset: 'numeric' }, function(err, testData) {
assert.equal(testData.length, testLength);
var search = testData.search(/\D/ig);
assert.equal(search, -1);
done();
});
});
it("accepts 'alphabetic' as charset option", function() {
var testData = random({ length: testLength, charset: 'alphabetic' });
var search = testData.search(/\d/ig);
assert.equal(search, -1);
it("accepts 'alphabetic' as charset option async", function(done) {
var testData = random({ length: testLength, charset: 'alphabetic' }, function(err, testData) {
var search = testData.search(/\d/ig);
assert.equal(search, -1);
done();
});
});
it("accepts 'hex' as charset option", function() {

@@ -46,2 +65,14 @@ var testData = random({ length: testLength, charset: 'hex' });

it("accepts 'binary' as charset option", function() {
var testData = random({ length: testLength, charset: 'binary' });
var search = testData.search(/[^01]/ig);
assert.equal(search, -1);
});
it("accepts 'octal' as charset option", function() {
var testData = random({ length: testLength, charset: 'octal' });
var search = testData.search(/[^0-7]/ig);
assert.equal(search, -1);
});
it("accepts custom charset", function() {

@@ -53,2 +84,11 @@ var charset = "abc";

});
it("accepts custom charset async", function(done) {
var charset = "abc";
random({ length: testLength, charset: charset }, function(err, testData) {
var search = testData.search(/[^abc]/ig);
assert.equal(search, -1);
done();
});
});

@@ -60,3 +100,3 @@ it("accepts readable option", function() {

});
it("accepts 'uppercase' as capitalization option", function() {

@@ -67,3 +107,3 @@ var testData = random({ length: testLength, capitalization: 'uppercase'});

});
it("accepts 'lowercase' as capitalization option", function() {

@@ -85,2 +125,19 @@ var testData = random({ length: testLength, capitalization: 'lowercase'});

it("returns unique strings async", function(done) {
var results = [];
function doTest() {
random(undefined, function(err, string) {
assert.equal(results.indexOf(string), -1);
results.push(string);
if (results.length >= 1000) {
done();
} else {
doTest();
}
});
}
doTest();
});
it("returns unbiased strings", function() {

@@ -107,2 +164,25 @@ var charset = 'abcdefghijklmnopqrstuvwxyz';

it("returns unbiased strings async", function(done) {
var charset = 'abcdefghijklmnopqrstuvwxyz';
var slen = 100000;
random({ charset: charset, length: slen }, function(err, s) {
var counts = {};
for (var i = 0; i < s.length; i++) {
var c = s.charAt(i);
if (typeof counts[c] === "undefined") {
counts[c] = 0;
} else {
counts[c]++;
}
}
var avg = slen / charset.length;
Object.keys(counts).sort().forEach(function(k) {
var diff = counts[k] / avg;
assert(diff > 0.95 && diff < 1.05,
"bias on `" + k + "': expected average is " + avg + ", got " + counts[k]);
});
done();
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc