<commit_before>const crypto = require('crypto')
const bindings = require('bindings')('argon2')
const Promise = require('any-promise')

const defaults = Object.freeze({
  timeCost: 3,
  memoryCost: 12,
  parallelism: 1,
  argon2d: false
})

const limits = Object.freeze(bindings.limits)
const internalLimits = new Map(Object.keys(bindings.limits).map(key => [key, bindings.limits[key]]))

const validate = (salt, options) => new Promise((resolve, reject) => {
  if (!Buffer.isBuffer(salt) || salt.length < 8) {
    reject(new Error('Invalid salt, must be a buffer with 8 or more bytes.'))
  }

  for (const [key, {min, max}] of internalLimits) {
    const value = options[key]
    if (!Number.isInteger(value) || value > max || value < min) {
      reject(new Error(`Invalid ${key}, must be an integer between ${min} and ${max}.`))
    }
  }

  resolve()
})

module.exports = {
  defaults,
  limits,

  hash(plain, salt, options) {
    options = Object.assign({}, defaults, options)

    return validate(salt, options).then(() => new Promise((resolve, reject) => {
      bindings.hash(new Buffer(plain), salt, options, resolve, reject)
    }))
  },

  generateSalt(length) {
    return new Promise((resolve, reject) => {
      crypto.randomBytes(length || 16, (err, salt) => {
        /* istanbul ignore if */
        if (err) {
          reject(err)
        }
        resolve(salt)
      })
    })
  },

  verify(hash, plain) {
    if (!/^\$argon2[di](\$v=\d+)?\$m=\d+,t=\d+,p=\d+(?:\$[\w+\/]+){2}$/.test(hash)) {
      return Promise.reject(new Error('Invalid hash, must be generated by Argon2.'))
    }

    return new Promise((resolve, reject) => {
      bindings.verify(hash, new Buffer(plain), resolve, reject)
    })
  }
}
<commit_msg>Revert Map, not consistently available through supported Node versions<commit_after>const crypto = require('crypto')
const bindings = require('bindings')('argon2')
const Promise = require('any-promise')

const defaults = Object.freeze({
  timeCost: 3,
  memoryCost: 12,
  parallelism: 1,
  argon2d: false
})

const limits = Object.freeze(bindings.limits)

const validate = (salt, options) => new Promise((resolve, reject) => {
  if (!Buffer.isBuffer(salt) || salt.length < 8) {
    reject(new Error('Invalid salt, must be a buffer with 8 or more bytes.'))
  }

  for (const key of Object.keys(limits)) {
    const {max, min} = limits[key]
    const value = options[key]
    if (!Number.isInteger(value) || value > max || value < min) {
      reject(new Error(`Invalid ${key}, must be an integer between ${min} and ${max}.`))
    }
  }

  resolve()
})

module.exports = {
  defaults,
  limits,

  hash(plain, salt, options) {
    options = Object.assign({}, defaults, options)

    return validate(salt, options).then(() => new Promise((resolve, reject) => {
      bindings.hash(new Buffer(plain), salt, options, resolve, reject)
    }))
  },

  generateSalt(length) {
    return new Promise((resolve, reject) => {
      crypto.randomBytes(length || 16, (err, salt) => {
        /* istanbul ignore if */
        if (err) {
          reject(err)
        }
        resolve(salt)
      })
    })
  },

  verify(hash, plain) {
    if (!/^\$argon2[di](\$v=\d+)?\$m=\d+,t=\d+,p=\d+(?:\$[\w+\/]+){2}$/.test(hash)) {
      return Promise.reject(new Error('Invalid hash, must be generated by Argon2.'))
    }

    return new Promise((resolve, reject) => {
      bindings.verify(hash, new Buffer(plain), resolve, reject)
    })
  }
}

{'fraction_non_alphanumeric': 0.17551963048498845, 'fraction_numerical': 0.007505773672055427, 'mean_word_length': 3.220462850182704, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7495477', 'n_tokens_mistral': 1167, 'n_tokens_neox': 1113, 'n_words': 284}