C,358字节
(只有三行代码,但是为了清晰起见,我将第三行分解了)
#define x putchar
#define y random()
c,n;main(){char*s[26]={"QS","HNV","FVX","EFSX","DRW","CDGR","FHTV","BGJY","KOU","HKNU",
"IJLM","KO","KN","BJM","ILP","OO","AW","EFT","ADWZ","GRY","IJY","BCG","ESQ","CDZ","HTU",
"SX"};while((c=getchar())>0){if(y%10>0&&x(c))continue;if(isalpha(c)&&y%3<1){n=(c&31)-1;
x(s[n][y%strlen(s[n])]|(c&32));continue;}if (y&1)x(x(c));}}
开头的字符串数组列出了字母表中每个字母可能的相邻键。我必须加倍“ O”(与“ P”相邻)以避免random()%1
在选择移位字符时进行计算。
测试运行:
$ echo "This is some correct text. It is too correct. Please un-correctify it." |./a.out
This is some cofrect teext. It is too correct.. Plleaase un-correctify it..
更新:
这是相同源代码的扩展和注释版本:
#include <stdio.h>
#include <string.h>
/* ^^ These should be included, but the code compiles without them */
int c,n;
void main() {
/* Adjacent keys for each letter of the alphabet (A, B, C, ..., Z): */
char *s[26] = { "QS","HNV","FVX","EFSX","DRW","CDGR","FHTV","BGJY","KOU","HKNU",
"IJLM","KO","KN","BJM","ILP","OO","AW","EFT","ADWZ","GRY","IJY",
"BCG","ESQ","CDZ","HTU","SX" };
/* Fetch input until null character or EOF reached */
while ((c=getchar())>0) {
/* For 90% of the time, just echo the character unchanged */
if (random()%10>0 && putchar(c)) continue;
/* If it's a letter of the alphabet, shift with 33% probability */
if (isalpha(c) && random()%3<1) {
/* Calculate offset to adjacent keys data */
n=(c&31)-1;
/* Choose a random adjacent key, and change to lower case if needed */
putchar(s[n][random()%strlen(s[n])]|(c&32));
continue;
}
/* If we reach this point, either we didn't fetch an alphabet character, or */
/* we did but chose not to shift it. Either way, we now need to either repeat */
/* the character or delete it, with 50% probability for each. */
/* This repeats the character by printing the return value from putchar() */
if (random()&1) putchar(putchar(c));
/* To delete the character, we don't have to do anything. */
}
}