function compare(data, hash, cb) { if (typeof data === 'function') { return process.nextTick(function() { data(new Error('data and hash arguments required')); }); } if (typeof hash === 'function') { return process.nextTick(function() { hash(new Error('data and hash arguments required')); }); } // cb exists but is not a function // return a rejecting promise if (cb && typeof cb !== 'function') { return promises.reject(new Error('cb must be a function or null to return a Promise')); } if (!cb) { return promises.promise(compare, this, [data, hash]); } if (data == null || hash == null) { return process.nextTick(function() { cb(new Error('data and hash arguments required')); }); } if (typeof data !== 'string' || typeof hash !== 'string') { return process.nextTick(function() { cb(new Error('data and hash must be strings')); }); } return bindings.compare(data, hash, cb); }
...
Note that both techniques achieve the same end-result.
#### To check a password:
```javascript
// Load hash from your password DB.
bcrypt.compare(myPlaintextPassword, hash, function(err, res) {
// res == true
});
bcrypt.compare(someOtherPlaintextPassword, hash, function(err, res) {
// res == false
});
```
### with promises
...
function compareSync(data, hash) { if (data == null || hash == null) { throw new Error('data and hash arguments required'); } if (typeof data !== 'string' || typeof hash !== 'string') { throw new Error('data and hash must be strings'); } return bindings.compare_sync(data, hash); }
...
As with async, both techniques achieve the same end-result.
#### To check a password:
```javascript
// Load hash from your password DB.
bcrypt.compareSync(myPlaintextPassword, hash); // true
bcrypt.compareSync(someOtherPlaintextPassword, hash); // false
```
### Why is async mode recommended over sync mode?
If you are using bcrypt on a simple script, using the sync mode is perfectly fine. However, if you are using bcrypt on a server,
the async mode is recommended. This is because the hashing done by bcrypt is CPU intensive, so the sync version will block the event
loop and prevent your application from servicing any other inbound requests or events.
## API
...
function genSalt(rounds, ignore, cb) { // if callback is first argument, then use defaults for others if (typeof arguments[0] === 'function') { // have to set callback first otherwise arguments are overriden cb = arguments[0]; rounds = 10; // callback is second argument } else if (typeof arguments[1] === 'function') { // have to set callback first otherwise arguments are overriden cb = arguments[1]; } if (!cb) { return promises.promise(genSalt, this, [rounds, ignore]); } // default 10 rounds if (!rounds) { rounds = 10; } else if (typeof rounds !== 'number') { // callback error asynchronously return process.nextTick(function() { cb(new Error('rounds must be a number')); }); } crypto.randomBytes(16, function(error, randomBytes) { if (error) { cb(error); return; } bindings.gen_salt(rounds, randomBytes, cb); }); }
...
```
#### To hash a password:
Technique 1 (generate a salt and hash on separate function calls):
```javascript
bcrypt.genSalt(saltRounds, function(err, salt) {
bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
// Store hash in your password DB.
});
});
```
Technique 2 (auto-gen a salt and hash):
...
function genSaltSync(rounds) { // default 10 rounds if (!rounds) { rounds = 10; } else if (typeof rounds !== 'number') { throw new Error('rounds must be a number'); } return bindings.gen_salt_sync(rounds, crypto.randomBytes(16)); }
...
```
#### To hash a password:
Technique 1 (generate a salt and hash on separate function calls):
```javascript
var salt = bcrypt.genSaltSync(saltRounds);
var hash = bcrypt.hashSync(myPlaintextPassword, salt);
// Store hash in your password DB.
```
Technique 2 (auto-gen a salt and hash):
```javascript
...
function getRounds(hash) { if (hash == null) { throw new Error('hash argument required'); } if (typeof hash !== 'string') { throw new Error('hash must be a string'); } return bindings.get_rounds(hash); }
n/a
function hash(data, salt, cb) { if (typeof data === 'function') { return process.nextTick(function() { data(new Error('data must be a string and salt must either be a salt string or a number of rounds')); }); } if (typeof salt === 'function') { return process.nextTick(function() { salt(new Error('data must be a string and salt must either be a salt string or a number of rounds')); }); } // cb exists but is not a function // return a rejecting promise if (cb && typeof cb !== 'function') { return promises.reject(new Error('cb must be a function or null to return a Promise')); } if (!cb) { return promises.promise(hash, this, [data, salt]); } if (data == null || salt == null) { return process.nextTick(function() { cb(new Error('data and salt arguments required')); }); } if (typeof data !== 'string' || (typeof salt !== 'string' && typeof salt !== 'number')) { return process.nextTick(function() { cb(new Error('data must be a string and salt must either be a salt string or a number of rounds')); }); } if (typeof salt === 'number') { return module.exports.genSalt(salt, function(err, salt) { return bindings.encrypt(data, salt, cb); }); } return bindings.encrypt(data, salt, cb); }
...
#### To hash a password:
Technique 1 (generate a salt and hash on separate function calls):
```javascript
bcrypt.genSalt(saltRounds, function(err, salt) {
bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
// Store hash in your password DB.
});
});
```
Technique 2 (auto-gen a salt and hash):
...
function hashSync(data, salt) { if (data == null || salt == null) { throw new Error('data and salt arguments required'); } if (typeof data !== 'string' || (typeof salt !== 'string' && typeof salt !== 'number')) { throw new Error('data must be a string and salt must either be a salt string or a number of rounds'); } if (typeof salt === 'number') { salt = module.exports.genSaltSync(salt); } return bindings.encrypt_sync(data, salt); }
...
#### To hash a password:
Technique 1 (generate a salt and hash on separate function calls):
```javascript
var salt = bcrypt.genSaltSync(saltRounds);
var hash = bcrypt.hashSync(myPlaintextPassword, salt);
// Store hash in your password DB.
```
Technique 2 (auto-gen a salt and hash):
```javascript
var hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
...
promise = function (fn, context, args) { //can't do anything without Promise so fail silently if (typeof Promise === 'undefined') { return; } if (!Array.isArray(args)) { args = Array.prototype.slice.call(args); } if (typeof fn !== 'function') { return Promise.reject(new Error('fn must be a function')); } return new Promise(function(resolve, reject) { args.push(function(err, data) { if (err) { reject(err); } else { resolve(data); } }); fn.apply(context, args); }); }
n/a
reject = function (err) { // silently swallow errors if Promise is not defined // emulating old behavior if (typeof Promise === 'undefined') { return; } return Promise.reject(err); }
...
}
if (!Array.isArray(args)) {
args = Array.prototype.slice.call(args);
}
if (typeof fn !== 'function') {
return Promise.reject(new Error('fn must be a function'));
}
return new Promise(function(resolve, reject) {
args.push(function(err, data) {
if (err) {
reject(err);
} else {
...