program code;

{$m 65520,0,655360}

type
  str4=string[4];

{  function pwr(x,y:longint):longint;
  var
    a,i:longint;
  begin
    a:=0;
    for i:=1 to y do
      a:=a+x;
    if y=0 then a:=1;
    pwr:=a;
  end;}

  procedure setrandseed(key:str4);
  var
    r:longint;
    i:integer;
  begin
    r:=0;
{    for i:=0 to length(key)-1 do
      r:=r+pwr(2,(i*8))*(ord(key[i+1]));}
    r:=(ord(key[1])*16777216 + ord(key[2])*65536) + (ord(key[3])*256 + ord(key[4]));
{    writeln('Your code number is: ',r);}
    randseed:=r;
  end;

  function encode(ch:char):char;
  var
    a:integer;
  begin
    a:=ord(ch)+random(256);
    while a>255 do a:=a-256;
    encode:=chr(a);
  end;

  function decode(ch:char):char;
  var
    a:integer;
  begin
    a:=ord(ch)-random(256);
    while a<0 do a:=a+256;
    decode:=chr(a);
  end;

  procedure encode_decode_file(s1,s2:string;ed:boolean);
  const bufsize=60000;
  var
    ch:char;
    f1,f2:file;
    c,d:longint;
    e,i:integer;
    l:word;
    buf:array [1..bufsize] of char;
  begin
    assign(f1,s1);
    assign(f2,s2);
    reset(f1,1);
    rewrite(f2,1);
    c:=0;
    e:=0;
    d:=filesize(f1);
    if ed then writeln('Encoding...') else writeln('Decoding...');
    write('   ');
    while not eof(f1) do
    begin
      blockread(f1,buf,bufsize,l);
      for i:=1 to l do
      begin
        ch:=buf[i];
        if ed then ch:=encode(ch) else ch:=decode(ch);
        buf[i]:=ch;
      end;
      c:=c+l;
      blockwrite(f2,buf,l,l);
      write(int(100*c/d):3:0,'% completed.');
      for i:=1 to 15 do write(chr(8));
    end;
    writeln('100% completed.');
    close(f2);
    close(f1);
  end;


  procedure main;
  var
    a:str4;
    i,b:integer;
    s1,s2:string;
    ch:char;
  begin
    write('Enter input file name: ');
    readln(s1);
    write('Enter output file name: ');
    readln(s2);
    a:='    ';
    write('Enter 4 letter key: ');
    readln(a);
    setrandseed(a);
    write('Encode or Decode? [E/D]: ');
    ch:=' ';
    while not (ch in ['e','E','d','D']) do readln(ch);
    if ch in ['d','D'] then encode_decode_file(s1,s2,false);
    if ch in ['e','E'] then encode_decode_file(s1,s2,true);
    writeln('Done.');
  end;

begin
  main;
end.
