code: func (s *Salt) GenerateWRounds(length, rounds int) []byte {
  	if length > s.SaltLenMax {
  		length = s.SaltLenMax
  	} else if length < s.SaltLenMin {
  		length = s.SaltLenMin
  	}
  	if rounds < 0 {
  		rounds = s.RoundsDefault
  	} else if rounds < s.RoundsMin {
  		rounds = s.RoundsMin
  	} else if rounds > s.RoundsMax {
  		rounds = s.RoundsMax
  	}
  
  	saltLen := (length * 6 / 8)
  	if (length*6)%8 != 0 {
  		saltLen += 1
  	}
  	salt := make([]byte, saltLen)
  	rand.Read(salt)
  
  	roundsText := ""
  	if rounds != s.RoundsDefault {
  		roundsText = "rounds=" + strconv.Itoa(rounds)
  	}
  
  	out := make([]byte, len(s.MagicPrefix)+len(roundsText)+length)
  	copy(out, s.MagicPrefix)
  	copy(out[len(s.MagicPrefix):], []byte(roundsText))
  	copy(out[len(s.MagicPrefix)+len(roundsText):], Base64_24Bit(salt))
  	return out
  }
docs: // GenerateWRounds creates a random salt with the random bytes being of the
  // length provided, and the rounds parameter set as specified.
  //
  // The parameters are set thus:
  //
  //   length > SaltLenMax: length = SaltLenMax
  //   length < SaltLenMin: length = SaltLenMin
  //
  //   rounds < 0: rounds = RoundsDefault
  //   rounds < RoundsMin: rounds = RoundsMin
  //   rounds > RoundsMax: rounds = RoundsMax
  //
  // If rounds is equal to RoundsDefault, then the "rounds=" part of the salt is
  // removed.