[Question]
  [
The domain server requires that all employees have a strong, random password conforming to the following rules:
* Exactly 15 characters long.
* Keyboard-typeable characters only (as shown in code-type below). Teaching the sales to use ALT+NUMPAD codes is not permitted.
* At least 1 lower case letter: `abcdefghijklmnopqrstuvwxyz`
* At least 1 upper case letter: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`
* At least 1 numeric digit: `0123456789`
* At least 1 symbol: ``~!@#$%^&*()_+-={}|[]\:";'<>?,./`
For this purpose IT have commissioned and will be distributing a Random Password Generator to all employees. All employees will be required to use the Random Password Generator. The requirements for the Random Password Generator are, in addition to the password restrictions above:
* It must be able to generate all permutations of all allowable characters.
* It must display the generated password on the screen.
* The code is required to be as small as possible (in bytes).
Please submit your proposed solution within the next week.
  
[Answer]
# Mathematica (18)
Let me a little cheat
```
= 15char ASCII pwd
```
> 
> 
> ```
> &(^F7yP8k:*1P<t
> 
> ```
> 
> 
P.S. not safety :)
[Answer]
# Ruby, 74 69 bytes
Just randomly sample from the ascii range 33 - 126 until all classes of characters are present:
```
$_=[*?!..?~].sample(15)*''until~/\d/&&~/[a-z]/&&~/[A-Z]/&&~/\W|_/
p$_
```
# Ruby, 39 bytes
Using moose's clever discovery:
```
p"0123abcdABCD-+/<".chars.sample(15)*''
```
---
Edit to satisfy the mob:
Note that the rules changed *after* I first posted this. At the time *both* the previous entries applied to the rules. I would also like to point out that the rules are still not too well defined:
> 
> (..) all permutations of all allowable characters
> 
> 
> 
"Permutations". There are ***no*** [permutations](http://en.wikipedia.org/wiki/Permutation) of the allowable characters that complies with the rest of the rules, because any permutation of the set of allowable characters is as long as the set of allowable characters itself (while the password is supposed to be 15 characters long). *And there are no repetitions in a permutation.* However my first entry is still more "random" than many of the other well upvoted answers here.
Nevertheless, here you have it. Allows repetitions of characters and underscore:
# Ruby, 77 bytes
```
$_=([*?!..?~]*15).sample(15)*''until~/\d/&&~/[a-z]/&&~/[A-Z]/&&~/\W|_/
puts$_
```
I also used `puts` instead of `p` in this one because `p` prints out the string enclosed in "quotation marks" and some characters escaped with a backslash.
# Ruby, 70 bytes
As Ventero points out, `~` can be skipped in front of the regexes, and `print` can replace `puts$_`. But with the ugly output this causes you might as well print all the rejected passwords too, squeezing it into a one-liner:
```
puts$_=([*?!..?~]*15).sample(15)*''until/\d/&&/[a-z]/&&/[A-Z]/&&/\W|_/
```
### Explanation
As requested. `$_` is a semi-magical variable that contains the last line read from input - so you don't always need to store it, like [this](https://codegolf.stackexchange.com/questions/17331/shrink-a-number-string/17356#17356). Here however we use it because of another property, namely that the [`~`](http://www.ruby-doc.org/core-2.0/Regexp.html#method-i-7E) operator applies a regex directly to it, a trick I first learned by [chron](https://codegolf.stackexchange.com/questions/11901/chess960-position-generator/11902#11902). I replaced the usage of `all`, but it should be quite easy to understand if you get the rest ([see the docs](http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-all-3F)).
[Answer]
# Java 8 - 354 329 319 275 267 characters
Just for fun, using lambdas with Java 8 - each possible output has the same probability of being found.
It uses the fact that the allowed characters have consecutive ascii codes, from 33 to 126.
```
class A {
    //flags for, respectively, small caps, large caps, digits, punctuation
    static int a, A, d, p;
    public static void main(String[] x) {
        String s;
        do {
            //Using special String constructor that takes an int[]
            s = new String(new java.util.Random().ints(15, 33, 127)
                                .toArray(),
                           0, 15);
            a = A = d = p = 0;
            s.chars()
                .map(c ->
                      c > 96 & c < 123 ? a = 1
                    : c > 64 & c < 90  ? A = 1
                    : c > 47 & c < 58  ? d = 1
                    : (p = 1))
                .min();
        } while (a + A + d + p < 4);
        System.out.println(s);
    }
}
```
Sample output:
```
.*;Tm?svthiEK`3  
o.dzMgtW5|Q?ATo  
FUmVsu<4JF4eB]1
```
Compressed program:
`class A{static int a,A,d,p;public static void main(String[]x){String s;do{s=new String(new java.util.Random().ints(15,33,127).toArray(),0,15);a=A=d=p=0;s.chars().map(c->c>96&c<123?a=1:c>64&c<90?A=1:c>47&c<58?d=1:(p=1)).min();}while(a+A+d+p<4);System.out.println(s);}}`
[Answer]
# Python 2.X + 3.X (229 characters): Generate and replace
## Idea
1. First make a list with 15 allowed symbols
2. Replace a random position `r` by a random digit
3. Replace a random position `s`, with `s != r`, by an upper case letter
4. The same for lower case letter and symbol as in 2 and 3.
## Code
```
from random import randint as r, shuffle as s
a=list(range(15))
p=a[:]
for i in range(15):
    a[i]=chr(r(32,126))
s(p)
a[p.pop()]=chr(r(48,57))
a[p.pop()]=chr(r(65,90))
a[p.pop()]=chr(r(97,122))
a[p.pop()]=chr(r(33,47))
print(a)
```
# Python 2.X + 3.X (194 characters): Generate and check
```
import random
from re import search as s
p=''
while not all([s("\d",p),s("[a-z]",p),s("[A-Z]",p),s("[\W_]",p)]):
 p=str(map(chr,[random.choice(list(range(33,127))) for i in range(15)]))
print(p)
```
* Thanks to [MvG](https://codegolf.stackexchange.com/users/13683/mvg) who told me that `\u` and `\l` does not exist in Python regex.
* Thanks to [grc](https://codegolf.stackexchange.com/users/4020/grc) who told me that [`random.sample`](http://docs.python.org/2/library/random.html#random.sample) is without replacement, be to get every possible allowed password we need sampling with replacement.
# Using flaw in the problem description
Currently, the problem description does not demand that every symbol / digit appears with the same probability. With the following solution, you cannot make any assumption about a single symbol and/or position. But you can do it with multiple ones.
## Python 2.X+ 3.X (62 characters)
```
from random import sample
print(sample("0123abcdABCD-+/<",15))
```
Thanks to daniero for the idea to use sample.
[Answer]
# Bash on \*nix (109)
```
while ! grep -Pq [A-Z].*[a-z].*[0-9].*[\\W_]<<<$a$a$a$a
do a=`tr -dc !-~</dev/urandom|head -c15`
done
echo $a
```
To work correctly, `$a` must not be set to a valid but non-random password up front. If you want to include `a=` and a line break up front, that's three more characters but it allows you to run the thing repeatedly. You can obviously also replace all newlines with `;` so you have a one-liner which you can execute as often as you whish.
Furthermore, you should have set `LC_ALL=C` or not set any locale-specific environment variables (`LANG` and `LC_CTYPE` in particular), since the character ranges depend on collation order being equal to ascii order.
`/dev/urandom` is the a source of random bytes. `!-~` is the range of all permissible characters, as specified in the question. `tr -dc` removes all characters *not* listed in its next argument. `head` takes 15 of the remaining characters. `grep` checks whether each of the required kinds does occur at least once. Its input consists of four copies of the candidate, so order of the symbols does not matter, hence all possible passwords stand a chance of getting selected. The `-q` to grep suppresses output.
For reasons unknown, `/dev/random` instead of `/dev/urandom` takes ages. It seems like entropy got exhausted pretty quickly. If you `cd` into `/dev`, you can avoid some more bytes, but that feels a bit like cheating.
# Python 2 (138)
```
import re,random
a=''
while not re.search('[A-Z].*[a-z].*[0-9].*[\W_]',a*4):
 a=''.join(random.sample(map(chr,range(33,127))*15,15))
print a
```
To make the code readable I added a newline and indentation after the loop which is not neccessary and which I did not count.
This is essentially the same idea as in the bash version. The random source here is `random.sample`, which will not repeat elements. To counter this fact, we use 15 copies of the list of permissible letters. That way, every combination can still occur, although those with repeated letters will occur less often. But I decide to consider this a feature, not a bug, since the question did not require equal probability for all permutations, only the possibility.
# Python 3 (145)
```
import re,random
a=''
while not re.search('[A-Z].*[a-z].*[0-9].*[\W_]',a*4):
 a=''.join(random.sample(list(map(chr,range(33,127)))*15,15))
print(a)
```
One newline and one indent again not counted. Apart from some Python-3-specific syntax overhead this is the same solution as for Python 2.
# JavaScript (161)
```
a=[];for(i=33;i<127;)a.push(s=String.fromCharCode(i++));
while(!/[A-Z].*[a-z].*[0-9].*[\W_]/.test(s+s+s+s))
for(i=0,s="";i<15;++i)s+=a[Math.random()*94|0];alert(s)
```
I added the newlines for readability, but did not count them.
# R (114)
```
s<-""
while(!grepl("[A-Z].*[a-z].*[0-9].*(\\W|_)",paste(rep(s,4),collapse="")))
 s<-intToUtf8(sample(33:126,15,T))
s
```
Linebreak and indentation inside loop added but not counted. If you feel like it, you can again move this to a single `;`-separated line.
[Answer]
# C# (123 - 139 103 - 127 characters compacted):
Using a perfectly adequate framework method in `System.Web.dll`:
```
class P
{
    static void Main()
    {
        Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15, 1));
    }
}
```
Compacted:
```
class P{static void Main()
{Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15,1));}}
```
Example:
```
b+m2ae0K:{dz7:A
```
Alternatively, take the value of the second parameter (`int numberOfNonAlphanumericCharacters`) from the command line:
```
class P
{
    static void Main(string[] a)
    {
        Console.WriteLine(System.Web.Security.Membership.GeneratePassword(15, int.Parse(a[0])));
    }
}
```
[Answer]
# R (~~301~~ 322 characters)
**Correction** forgot to check for digits.
```
a='abcdefghijklmnopqrstuvwxyz';
f=as.factor(strsplit(paste(a,toupper(a),
    sep="0123456789`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./"),"")[[1]]);
g=gsub("(.):","\\1",levels(q:q:q:q:q:q:q:q:q:q:q:q:q:q:q));
repeat{p=g[runif(1)*length(g)]; 
    if(grepl("[A-Z]",p)&&grepl("[a-z]",p)&&grepl("[0-9]",p)&&grepl("[^A-Za-z0-9]",p))break;};
print(p);
```
(whitespace added for clarity only).
Generates all possible 15-character permutations of the 94 characters. Then randomly selects one until it matches the criteria. 
The magic is in the `q:q` operation, which generates a new factor data type that is the [interaction of all the factors in the first `q` list with all the factors in the second list](http://astrostatistics.psu.edu/datasets/R/html/base/html/seq.html), with every possible combination of those two lists being included in the list of "levels" of that factor. Interact 15 copies of the list of allowed characters, and you get (94^15) possible levels.
Please do not try this at home. The code takes a couple seconds to figure out all the three-character permutations, I really can't imagine how long it would take to figure out all the 15-character permutations, if your computer didn't just run out of memory in the meantime. When I ran the finished (three-character password) script to check it, the first password it spit out was "oO=", which I think about sums up the reaction you should have to this code.
[Answer]
# Mathematica 170
```
r=RandomSample;f[i_]:=(FromCharacterCode/@Range@@i);
{t,A,a,n}=f/@{{33,126},{65,90},{97,122},{48,57}};
s=Complement[t,A,a,n];
""<>r[Join[RandomChoice/@{A,a,n,s},r[t,11]],15]
```
**Examples**
"<]}Pg3/e?3+Z~Oz"  
"X/8jWe@f(\_x5P:="  
"2wz2VQhtJC?\*R7^"
[Answer]
## Python 2.7 (182)
```
import random as r,string as s
z=r.sample
j=list(z(s.ascii_lowercase,12)+z(s.ascii_uppercase,1)+z(s.digits,1)+z('`~!@#$%^&*()_+-={}|[]\\:";\'<>?,./',1))
r.shuffle(j)
print ''.join(j)
```
[Answer]
**Golfscript (60)**
Since the obl. golfscript is missing and as a noob I need the practice anyway :)
```
[48 10{rand}:r~+65 26r+97 26r+33 15r+11,{;32 96r+}%~]{r}$''+
```
It just builds an array with the 4 required + 11 random characters and sorts in random order.
[Answer]
# JavaScript 258 240 233 225
```
R=Math.random;a=b=>b[b.length*R()|0];for(x=[a(l="abcdefghijklmnopqrstuvwxyz"),a(u=l.toUpperCase()),a(n="0123456789"),a(s="`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./")];15>x.length;x.push(a(l+u+n+s)));alert(x.sort(y=>.5-R()).join(""))
```
Using a rule where:
`function(x){return x*x}` can be re-written as `function(x)x*x`. Only seems to work for functions returning a value.
Next iteration, reduced `x.sort(function().5-R())` to `x.sort(y=>.5-R())`
Next iteration, reduced further with fat arrow notation, which sadly only works for Firefox 22 and above.
[Answer]
## JavaScript (269 characters compacted)
For clarity, this is the code *before* I compacted it down [JS-Fiddle of it](http://jsfiddle.net/IQAndreas/qsPEc/2/):
```
var lowerLetters = "abcdefghijklmnopqrstuvwxyz";
var upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var numbers = "0123456789";
var symbols = "`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./";
var allCharacters = lowerLetters + upperLetters + numbers + symbols;
String.prototype.randomChar = function() {
    return this[Math.floor(this.length * Math.random())];
}
var minLength = 15;
var result = [];
// Start off by picking one random character from each group
result.push(lowerLetters.randomChar());
result.push(upperLetters.randomChar());
result.push(numbers.randomChar());
result.push(symbols.randomChar());
// Next, pick a random character from all groups until the desired length is met
while(result.length < minLength) {
    result.push(allCharacters.randomChar());
}
result.shuffle(); // Finally, shuffle the items (custom function; doesn't actually exist in JavaScript, but is very easy to add) -> http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
result.join("");
```
Here it is compacted down to 269 characters ([JS-Fiddle of it](http://jsfiddle.net/IQAndreas/qsPEc/8/)):
```
l="abcdefghijklmnopqrstuvwxyz";
u=l.toUpperCase();
n="0123456789";
s="`~!@#$%^&*()_+-={}|[]\\:\";'<>?,./";
R=Math.random;
function r(t){
    return t[~~(t.length*R())]
}
for(x=[r(l),r(u),r(n),r(s)];x.length<15;x.push(r(l+u+n+s)));
x.sort(function(){return .5-R()});
alert(x.join(""));
```
[Answer]
# Clojure (63):
```
(->> (map char (range 33 127)) (shuffle) (take 15) (apply str))
```
But need to be improved to ensure that containing at least 1 character of each category (Upper, Lower, Digit, Symbol).
[Answer]
# In sql-server
```
declare @a nvarchar(28)
set @a='abcdefghijklmnopqrstuvwxyz'
declare @b nvarchar(max)
set @b='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
declare @c nvarchar(max)
set @c='0123456789'
declare @d nvarchar(max)
set @d='~!@#$%^&*()_+-={}|[]\:";<>?,./'
select left(substring(@a,cast(rand()*10 as int),3)+substring(@b,cast(rand()*10 as int),6)+substring(@c,cast(rand()*10 as int),3)+substring(@d,cast(rand()*10 as int),5),15)
```
# [See it in action--1](http://www.sqlfiddle.com/#!6/c28a0/1)
# [see it in Action--2](http://www.sqlfiddle.com/#!6/d41d8/13535)
[Answer]
## SAS (191)
```
%macro c(p);compress(p,,"&p")ne''%mend;data x;length p$15;do x=1by 1;do t=1to 15;substr(p,t,1)=byte(ranuni(7)*94+33);end;if %c(kd)and %c(kl)and %c(ku)and %c(ad)then do;put p;stop;end;end;run;
```
`*TQP,(f=h10*)S=`
Commented/indented:
```
%macro c(p); /*compress removes or keeps certain classes of characters*/
  compress(p,,"&p")ne''
%mend;
data x;
length p$15;
do x=1by 1;
    do t=1to 15;
        substr(p,t,1)=byte(ranuni(7)*94+33); /*give it a 33-126, byte discards the noninteger portion rounding down*/
    end;
    if %c(kd)and %c(kl)and %c(ku)and %c(ad)then do; /*k=keep d=digit l/u=lower/upper ad=remove digits and alphas*/
        put p;
        stop;  /*met our requirement, head home*/
    end;
end;
run;
```
[Answer]
# PowerShell: 119
**Gofled Code**
```
for(;!($x-cmatch'.*(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!-/:-@[-`{-~]).*')){$x='';1..15|%{$x+=[char](33..126|random)}}$x
```
**Un-golfed and Commented**
```
# Start for loop definition.
for(
    # Skip variable initialization, start definition of run condition.
    ;
    # Loop runs if $x does not meet complexity requirements.
    # Length requirement is not tested here because it is enforced by the generator later.
    # Much thanks to @VasiliSyrakis for the RegEx help.
    !($x-cmatch'.*(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!-/:-@[-`{-~]).*')
)
{
    # Reset $x in case the script block has already run.
    $x='';
    # Use ForEach-Object, via the % alias, to run a loop 15 times.
    1..15|%{
        # Append a random ASCII character from 33-126 to $x.
        # Note: Use get-random instead of random for faster performance.
        $x+=[char](33..126|random)
    }
}
# Display $x.
$x
# Variable cleanup - not included in golfed code.
rv x
```
[Answer]
**Python 2.7 (149)**
```
from random import*
''.join(map(lambda x:chr(randint(*(x[1]or(32,126)))),sorted(map(None,sample(range(15),15),((48,57),(65,90),(97,122),(33,47))))))
```
Written out in a more readable (and not executable) way;
```
from random import *
''.join(                                          # Concatenate characters to string
  map(                                            # Map all characters using below lambda
    lambda x:chr(randint(*(x[1] or (32, 126)))),  # Map a single range to a random character
                                                  # within a specific range if supplied,
                                                  # otherwise the default "all" range.
    sorted(                                       # After distributing ranges, sort
      map(None,                                   # zip_longest alternative, distributes the
                                                  # required ranges over 4 random positions
        sample(range(15), 15),                    # 0-14 in random order
        ((48, 57), (65, 90), (97, 122), (33, 47)) # The 4 required ranges
      )
    )
  )
)
```
Fairly straight forward and surprisingly not much longer than a "generate, retry on match fail" version.
[Answer]
**PSQL (189)**
Feels like PSQL is a bit verbose... :)
```
SELECT ARRAY_TO_STRING(ARRAY_AGG(CHR((TRUNC((b-a)*RANDOM()+a))::int)ORDER BY RANDOM()),'')FROM(SELECT 32 a,127 b FROM generate_series(1,11)UNION ALL VALUES(48,58),(65,91),(97,123),(33,48))a
```
[SQLfiddle demo](http://sqlfiddle.com/#!15/d41d8/842).
[Answer]
## PHP, 235 225
This script shuffles characters around and then is checked via RegEx to make sure the password is strong (or it is regenerated).
```
<?php
while(!preg_match('/^(?=.*[A-Z])(?=.*[^A-Za-z])(?=.*[0-9])(?=.*[a-z]).{15}$/',$p)){ $p = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`~!@#$%^&*()_+-={}|[]\:";\'<>?,./'),0,15); }
echo $p;
```
[Answer]
**Javascript (209)**
```
r=Math.random;function t(x,y){return String.fromCharCode(Math.floor(y*r()+x))};x=[t(33,14),t(48,10),t(65,26),t(97,26)];for(i=0;i<11;i++)x.push(t(32,95));console.log(x.sort(function(){return r()-0.5}).join(''))
```
Semi-ungolfed;
```
// Return a character in the range [x,x+y)
function t(x,y) { return String.fromCharCode(Math.floor(y*Math.random()+x)) }
// Prefill required ranges
x=[ t(33,14), t(48,10), t(65,26), t(97,26)]
// Push 11 totally random (valid) characters
for(i=0; i<11; i++)
  x.push(t(32,95))
// Shuffle and output as string
console.log(x.sort(function(){return Math.random()-0.5})
             .join(''))
```
[Answer]
## Perl, 92
Not as concise as the Ruby answer, but I'm sure a Perl wizard could make this even shorter... I'm not too happy with all the `m//`s at the end, but seems to work and should satisfy the conditions to eventually generate all permutations.
```
do{$_=join"",map{(map{chr}33..127)[rand 94]}0..14}while!(/[A-Z]/&/[a-z]/&/\d/&/[\W_]/);print
```
Sample usage:
```
perl -e 'do{$_=join"",map{(map{chr}33..127)[rand 94]}0..14}while!(/[A-Z]/&/[a-z]/&/\d/&/[\W_]/);print'
```
Edited to fix validation and change `[[:punct:]]` to `[\W_]` after MvGs comments.
[Answer]
## Java 7 (~~270~~ 234 characters)
The premise is the same used by @assylias with java 8 (generate random passwords until valid password). However, instead of using lambdas, the password is generated by iterating a char array and validated by matching a regex.
```
class A {
  public static void main(String [] a) {
    byte[] b = new byte[15];
    String s;
    do {
      new java.util.Random().nextBytes(b);
      s = new String(b);
    } while(!s.matches("(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)(?=.*?[!-/:-@\\[-`]).*"));
    System.out.println(s);
  }
}
```
Minified Code:
```
class A {public static void main(String[] a){byte[] b=new byte[15];String s;do{new java.util.Random().nextBytes(b);s=new String(b);}while(!s.matches("(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)(?=.*?[!-/:-@\\[-`]).*"));System.out.println(s);}}
```
[Answer]
# Powershell
---
## One Liner version (143 bytes)
```
sal g random;1..11|%{$P+=[char](33..126|g)};(65..90|g),(97..122|g),(48..57|g),(33..47+58..64+123..126|g)|%{$P=$P.insert((1..11|g),[char]$_)};$P
```
## Mini version (146 bytes)
```
sal g random
1..11|%{$P+=[char](33..126|g)}
(65..90|g),(97..122|g),(48..57|g),(33..47+58..64+123..126|g)|%{$P=$P.insert((1..11|g),[char]$_)}
$P
```
## Readable version (860 bytes)
```
function pwgen {
    # Fulfill Upper,Lower,Digit,Symbol requirement by predefining ASCII ranges for each
    # These will be added into the string beginning at line 24
    [array[]]$symbolrange = (33..47),(58..64),(123..126)
    [char]$upper = (get-random (65..90))
    [char]$lower = (get-random (97..122))
    [char]$digit = (get-random (48..57))
    [char]$symbol = $symbolrange | get-random
    [char[]]$requirement = $upper + $lower + $digit + $symbol
    # Create the first 11 characters using any ASCII character between 32 - 126
    foreach ($number in (1..11)) {
        [string]$pass += [char](get-random (33..126))
    }
    # Insert each requirement character at a random position in the string
    foreach ($char in $requirement) {
        [string]$pass = $pass.insert((Get-Random (1..11)),$char)
    }
    return $pass
}
```
> 
> Credit to Iszi for various tips to shorten the code.
> 
> 
> 
[Answer]
# Factor, 196 characters
Same algorithm as MvG and moose's. It is not the shortest but should satisfy all the (current) criteria in the question:
```
USING: io kernel math pcre random sequences sequences.repeating ;
[ 15 94 random-integers [ 33 + ] "" map-as dup 60 cycle
"[A-Z].*[a-z].*[0-9].*[\\W_]" findall { } = not ] [ drop ] until print
```
[Answer]
# C - 154 characters
```
char p[16],c,f,w;main(){srand(time());while(f^15){c=p[15]=f=0;while(c^15){w=33+rand()%94;f|=w
>96&&w<123?1:w>47&&w<59?2:w>64&&w<91?4:8;p[c++]=w;}}puts(p);}
```
How do I hate `srand()`? Let me count the ways.
[Answer]
# Haskell, 192
```
import System.Random
main=getStdGen>>= \g->(print.(take 15))$until((\x->all(any(`elem`x))[['a'..'z'],['A'..'Z'],['0'..'9'],['!'..'/']++":;<=>?@[\\]^_`{|}~"]).(take 15))tail$randomRs('"','~')g
```
The printed string has quotes around it and escapes the backslash and quote characters; if that's unacceptable, `print` can be replaced with `putStrLn` for 3 more bytes. Here's a more readable version:
```
import System.Random
main = do
    g <- getStdGen
    let chars = randomRs ('"', '~') g
    let password = take 15 $ until (hasChars.(take 15)) tail chars
    print password
hasChars :: String -> Bool
hasChars x = all (any (`elem` x)) $
    [ ['a'..'z']
    , ['A'..'Z']
    , ['0'..'9']
    , "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
    ]
```
It's quite straightforward, it just creates an infinite/lazy list of random ASCII characters in the range `'!'` to `'~'`, then tosses out the first element until the first 15 characters have at least one character from each string of required characters.
[Answer]
### Excel VBA, 209 bytes
```
For i = 1 To 15
x = x + Chr(Int(90 * Rnd + 33))
Next
p = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+$"
With New RegExp
.Pattern = p
Set m = .Execute(x)
If m.Count = 0 Then
MsgBox "redo"
Else
MsgBox x
End If
End With
```
Randomly generates 15 ASCII characters so all possible combinations are possible.
Then uses a regular expression pattern to check if it contains at least one of each criteria.
If it does then the password is displayed, if not "redo" is displayed.
Credit to Bart Kiers for the Regular Expression pattern: <https://stackoverflow.com/questions/1559751/regex-to-make-sure-that-the-string-contains-at-least-one-lower-case-char-upper>
[Answer]
# [Python 3](https://docs.python.org/3/) + [passgen](https://pypi.org/project/passgen/), 64 bytes
```
import passgen as p
print(p.passgen(length=15,punctuation=True))
```
**If you have any suggestions for improvement, let me now in the comments!**
[Try it online!](https://tio.run/##K6gsycjPM/7/PzO3IL@oRKEgsbg4PTVPIbFYoYCroCgzr0SjQA8qqJGTmpdekmFraKpTUJqXXFKaWJKZn2cbUlSaqqn5/z8A "Python 3 – Try It Online") (or rather don't, as the `passgen` module isn't on TIO)
Github:
<https://github.com/EacyCoding/Password_Generator>
or in one line:
```
import passgen as p;print(p.passgen(length=15,punctuation=True))
```
Sample Outputs:
```
;dLjI3pr7541(CW
3ptRCt%OK^8+iW;
dDZk7^1!53rG$3M
```
[Answer]
## AutoHotkey 352
```
global o:={}
loop 4
o[c()]:=o(A_index-1)
loop 11
o[c()]:=o(m(r(),4))
loop 15
s.=o[A_index-1]
msgbox % s
r(){
Random,z
return z
}
m(z,r){
return mod(z,r)
}
c(){
while o[t:=m(r(),15)]!=""
j++
return t
}
o(f){
r0:=48,l0:=10,r1:=97,l1:=l2:=26,r2:=65
r := chr(r%f%+m(r(),l%f%))
if f=3
r:=Substr("``~!@#$%^&*()_+-={}|[]\:"";'<>?,./",m(r(),32)+1,1)
return r
}
```
**Using** - Just run the script
[Answer]
## Python (121 characters)
Makes use of the fact that you can multiply lists in Python [1,2,3] \* 2 gives [1,2,3,1,2,3]. Imports random. Numbers in a list multiplied by three are borders between ranges in ascii table for needed characters, e.g. [65, 90] maps to uppercase letters.
```
print "".join([random.choice([chr(i) for i in range(z[0],z[1])]) for z in [[33,48],[48,58],[58,65],[65,90],[90,123]]* 3])
```
]