here is my try :

[pascal]
unit rndname;
{
rndname.pas unit
(C) 2010 lowercase - news431-516@yahoo.fr
Freeware/do whatever you like, but don't claim autorship for this
code, please.
Use at your own risk. Might be buggy.

Contents :
----------

Quick and dirty functions to generate random names, using
"pseudo markov chain" (no maths here).

How to use :
------------

1) load or build a dictionnary
2) just call CreateName
}

interface

uses classes, sysutils;

Procedure BuildDictionnary(afile : string);
//build a dictionnary from any text file
procedure SaveDictionnary(filename : string);
//Save a dictionnary into a file
procedure LoadDictionnary(filename : string);
//Load a dictionnary from an existing file
Function CreateName: string;
//the main goal : generate a name

implementation

Type
TDictionnary = array[0..26,0..26] of integer;
// holds the chars stats from A to Z and the last is space

const
ValidChars = 'ABCDEFGHJKLMNPQRSTUVWXYZ';

var
Dic : TDictionnary;
DicLoaded : boolean = false;

procedure UpdateDictionnary(char1, char2 : char);
var
pos1, pos2 : integer;
val : integer;
begin
pos1 := ord(char1) - 65 ;
pos2 := ord(char2) - 65 ;
if (char2=' ') then pos2 := 26;
val := dic[pos1,pos2];
val := val + 1 ;
dic[pos1,pos2] := val;
end;

procedure SaveDictionnary(filename : string);
var
F : Tfilestream;
begin
F := Tfilestream.Create(filename, fmcreate or fmopenreadwrite or fmsharedenynone);
try
F.Write(dic, Sizeof(dic));
finally
F.Free;
end;
end;

procedure LoadDictionnary(filename : string);
var
F : Tfilestream;
begin
F := Tfilestream.Create(filename, fmopenread or fmsharedenynone);
try
F.read(dic, Sizeof(dic));
finally
F.Free;
dicloaded := true;
end;
end;

Procedure BuildDictionnary(afile : string);
var
F : Tstringlist;
buffer : string;
k,i,j,len : integer;
c1,c2 : char;
begin
F:= Tstringlist.Create;
try
F.LoadFromFile(afile);
//compute combinations
for k := 0 to F.Count - 1 do
begin
buffer := f.Strings[k];
len := length(buffer);
buffer := uppercase(buffer);
for i := 1 to len do
begin
if buffer[i] <> ' ' then
begin
c1 := buffer[i];
if ((i+1) > len) then
UpdateDictionnary(c1,' ')
else
begin
c2 := buffer[i+1];
if c2= ' 'then UpdateDictionnary(c1,' ')
else UpdateDictionnary(c1,c2)
end;
end;
end;
end;

//average the result;
for i := 0 to 26 do
begin
len := 0;
for j := 0 to 26 do
begin
len := len + dic[i,j];
end;
if len > 0 then
for j := 0 to 26 do
begin
k := dic[i,j];
k := round(k * 100 / len);
dic[i,j] := k
end;
end;

finally
F.Free;
//SaveDictionnary;
dicloaded := true;
end;
end;

Function LookupNextChar(c : char; var dostop : boolean) : char;
var
pos,i : integer;
val, j : integer;
l : char;
charset : string;
begin
result := ' ';
charset := '';
pos := ord(c) - 65 ;
for i := 0 to 26 do
begin
val := dic[pos,i];
if val <> 0 then
begin
if i = 26 then
l := ' '
else
l := chr(65+i);
for j := 0 to val-1 do
charset := Charset + l;
end;
end;
dostop := (Length(charset) = 0);
if not(dostop) then
result := charset[Random(Length(charset)) + 1];
if result = ' ' then dostop := true;
end;

Function CreateName: string;
var
buffer : char;
maxlen,len : integer;
stop : boolean;
begin
if not DicLoaded then exit;
maxlen := random(4)+ 4;
repeat
result := '';
buffer := ValidChars[Random(Length(ValidChars)) + 1];
Result := result + buffer;
stop :=false;
repeat
buffer:=lookupnextchar(buffer,stop);
Result := result + buffer;
len :=length(Result);
until (len > maxlen) or stop;
until (len > maxlen);
end;

initialization
Randomize;
end.
[/pascal]