Your CGI script probably has access to $ENV{HTTP_ACCEPT_CHARSET} && $ENV{HTTP_ACCEPT_LANGUAGE}
Checking for adjacent characters seems like a relatively trivial use for a hash of arrays or an array of arrays, once you know which keyboard map is being used & how that map is laid out.