##JS, 303##

    function z(s){return s.split('').map(function(d){if((r=Math.random)()>.1)return d
    if((c=r()*(/[a-z]/i.test(d)?3:2))<2)return c>1?d+d:''
    if((x=(b="qwertyuiop0asdfghjkl000zxcvbnm").indexOf(d))<0)x=(b=b.toUpperCase()).indexOf(d)
    for(a=0,n=11;i=!a;a=b[x+n])for(v=r()*4;v>i;n=i++%2?-n:1);return a}).join('')}

Algorithm for the keyslip:

 - find char in string (or uppercase)
 - add 11, -11, 1 or -1 to the index.
 - if it's invalid (0 or null), re-roll


Non-Golfed version per request:

    function z (s) {
      return s.split('') // split input string into characters.
              .map( // and then for each character...
        function (d) {
          r = Math.random; // set up a shortened form of Math.random
          if (r() > .1) {  // normal case
            return d;
          }
          numOptions = /[a-z]/i.test(d) ? 3 : 2; // if it's a character, three options
          c = r() * numOptions; // chars can be 0-3, non-chars: 0-2
          if (c < 2) {                // this case is simple, so it comes first
            return c>1 ? d + d : ''; // double or omit.
          }

          // we must be in keyslip mode.
          b = "qwertyuiop0asdfghjkl000zxcvbnm"; // keyboard map
          x = b.indexOf(d);  // x marks the spot
          if (x < 0) {  // not here? must be a capital letter!
            b = b.toUpperCase();
            x = b.indexOf(d);
          }

          // in the golfed code, these while loops become for loops, 
          // but it's really a while.
          a = 0, n = 11, i = 1;
          while (!a) { // that is, a != null && a != 0
            i = 1;
            v = r() * 4; // so v is a random number <= 4
            while (v > i) { 
              n = i++ % 2 ? -n : 1; // n steps in this pattern: [11, -11, 1, -1]
            }
            a = b[x+n];  // slip the key
          }
          return a;
        }
      ) // end the map function
      .join('') // and then reassemble the string
    }