0

我以前从未使用过 Foxpro。您能否将以下 Foxpro 代码转换为 c#,以便我理解逻辑。我主要对密码逻辑感兴趣。还有什么是spac()?can_p 是存储用户名密码的 .dbf 文件。但密码以数字形式存储在几列(k1,k2...k12)中。我猜系统从密码中计算出这 12 个数字并输入那里。

proc can_01
set colo to w/
@10,18 clea to 17,60
@10,18 to 17,60 doub
set colo to n/w
@10,34 say ' LOG IN '
set colo to w/
@12,20 say 'Enter Name.......'
@13,20 say 'Counter..........'
usr=spac(18)
cntr='*'
x=1
do whil .t.
set colo to n/w
@22,0
@22,0 say ;
  'Enter user name                 <CR>-Exit                 <ESC>-Abort '
set colo to n/w,w+/bg
@12,38 get usr pict '!!!!!!!!!!!!!!!!!'
read
set colo to n/w
if read()=12 .or. usr='        ' .or. x>3
  @22,0
  @22,0 say 'Log In aborted..Press any key..'
  ??chr(7)
  do can_011
  read
  quit
endi
x=x+1
use can_p
set exac on
loca for user=trim(usr)
set exac off
@22,0
if  eof()
  @22,0 say 'User '+usr+' does not exists..Press any key..'
  ??chr(7)
  use
  read
 else
  exit
  endi
 endd
 do whil .t.
 @22,0 say ;
  'Enter Counter No                <CR>-EXIT                   <ESC>-Abort'
 @13,38 get cntr pict '!'
 read
 @22,0
 if read()=12
  do can_011
  quit
 endi
 if trim(usr)='BABU M' .and. cntr='*'
  exit
 endi
 if .not. cntr$'ABCD'
  @22,0 say 'Incorrect Counter..Re-enter..'
  ??chr(7)+chr(7)
  loop
 endi
 exit
  endd
  scntr=cntr
 x=1
do whil .t.
set colo to n/w
@22,0
@22,0 say ;
  'Enter Password              <CR> - Exit                <ESC> - Abort '
 set colo to w/
 @14,20 say 'Enter PASSWORD :-'
 set cons off
 @14,38 say ''
 acce to ps
 set cons on
 cps=chr(k8+9)+chr(k4+7)+chr(k5-31)+chr(k1+13)+chr(k3-19)+;
  chr(k7-35)+chr(k2-27)+chr(k6+1)+chr(k11-6)+chr(k10+6);
  +chr(k12+11)+chr(k9-5)
  set colo to n/w
  @22,0
  set exac on
  if cps<>ps
  @22,0 say 'Incorrect PASSWORD !! Press any key ..'
  ??chr(7)
  read
  x=x+1
  if read()=12 .or. x>3
     do can_011
     quit
  endi
  else
  exit
  endi
 endd
 @22,0
 @22,0 say 'Please Wait..'
 set exac off
 if user#'JV'
  if .not. (counter=scntr .and. active)
  @22,0 say 'Counter not activated...Access denied..Return to system..'
  ??chr(7)+chr(7)+chr(7)+chr(7)
  do can_011
  quit
   endi
   endi
  xr=recn()
  loca for counter=scntr .and. li .and. recn()<>xr
  if found()
   @22,0 say 'Counter already Logged-In by User '+user+;
  '..Return to system..'
    ??chr(7)+chr(7)+chr(7)+chr(7)
    do can_011
    quit
    endi
   go xr
   repl active with .t.,li with .t.,lidt with date(),litm with time()
    unlo
    do can_011
   set colo to w/n,w+/g
     retu
4

1 回答 1

1

although I can write a C# WinForms and WPF to do it, I'll try to explain all the way through from Foxpro perspective... Mind you... this looks to be a decompiled version of the code as all the foxpro keywords are only showing in 4 characters, not their complete and more understandable commands. Also, this is code that looks like it was written before VFP even existed... much like older DOS days, going back to... 1989 days...

&& "Proc" is short for Procedure (or Func for Function) much like method in C#, 
public Can_01()
{ do things here... }

proc can_01

&& "SET COLO" = Set Color to
set colo to w/
&&  @x,y to x2,y2 does basic drawing, such as clear screen ( via CLEA TO = "clear to" )
&& from a DOS world of 24x80 as this appears to reflect, then draw a double border (via DOUB)
@10,18 clea to 17,60
@10,18 to 17,60 doub

&& change "COLO"r again
set colo to n/w

&& At given x/y coordinate (10,34), show a string for "LOG IN", 
@10,34 say ' LOG IN '
&& another color change
set colo to w/
&& at x,y, show string label for respective
@12,20 say 'Enter Name.......'
@13,20 say 'Counter..........'

&& create variable "usr" and set it equal to 18 spaces
usr=spac(18)
&& create var "cntr" and default it to a single "*"
cntr='*'
&& create var "x" and set to 1
x=1

&& Loop... do while true -- continues until and "ENDDO"
&& in C#...  while( true ) {  do things... }
do whil .t.
   && more coloring and showing fixed-spacing label to the screen
   && to give user indicator of allowed input of <CR> carriage return to exit
   && or escape key to abort, but still show a label and more coloring.
   set colo to n/w
   @22,0
   @22,0 say ;
     'Enter user name                 <CR>-Exit                 <ESC>-Abort '
   set colo to n/w,w+/bg  

   && @/Get is actually getting user input from given x,y coordinate.
   && the "pict" is a picture clause like an input format string.  "!" means
   && convert entered characters to upper case, and only allow as many characters
   && as there are "!" in the picture mask.
   && put whatever is typed into the variable "usr"
   @12,38 get usr pict '!!!!!!!!!!!!!!!!!'

   && stop and wait for user input until they hit enter or escape
   read
   && more color changing
   set colo to n/w

   && read() or "ReadKey()" checks input length, that otherwise is the same as mask-- 
   && redundant.  OR the user name is all spaces OR the x counter is now past 3rd attempt
   if read()=12 .or. usr='        ' .or. x>3
      && show to screen login aborted
      @22,0
      @22,0 say 'Log In aborted..Press any key..'
      && send a DOS "beep" to the user
      ??chr(7)
      && do another procedure or function called "can_011" ( I guess is some "cancel" process)
      do can_011
      && read will basically wait for confirmation via simple message of "Press any key..."
      read
      && quit entire application
      quit
   endi


   && user did provide input, increase the attempted login counter x=x+1
   x=x+1

   && open the table called "CAN_P"
   use can_p
   && set exact matching on... to prevent things like finding "Tom" = "Tom   "
   set exac on
   && try to "LOCATE"  for the specific user entered exists within the table
   && but trimming the value entered by the user (  C#  string.Trim()  )
   loca for user=trim(usr)
   && turn exact matching back off
   set exac off

   @22,0
   && if EOF() (end of file) is reached, we did not find the user
   if  eof()
      && show message to user at x,y position
      @22,0 say 'User '+usr+' does not exists..Press any key..' 
      && another DOS bell
      ??chr(7)
      && close the "CAN_P" table
      use
      && wait for user to press a key to try via next loop
      read
   else
      && we found the record in the table, exit the do/while loop
      exit
   endi
endd  && end of the do/while loop

&& another do while true...
&& almost identical in content, but asking for some "cntr" variable.
&& almost same display, showing counter attempts and prompting
do whil .t.
   @22,0 say ;
      'Enter Counter No                <CR>-EXIT                   <ESC>-Abort'
   && prompt user for a value to put into the "cntr" variable, single character
   @13,38 get cntr pict '!'
   && read input
   read
   @22,0
   if read()=12
      && again, forcing itself out via "CAN_011" procedure somewhere else
      do can_011
      quit
   endi

   && if the user name is equal to "BABU M" and t he cntr = "*", exit the do/while loop
   if trim(usr)='BABU M' .and. cntr='*'
      exit
   endi

   && "$" in VFP is like "contains" in C#
   && in C#... string myLongString = "testing for some value to look for";
   &&          string myLongString.Contains( " val" );
   && 
   && in this case, 'cntr" is a single character value.  and if it is NOT
   && and "A", "B", "C" or "D", tell user incorrect and re-enter
   if .not. cntr$'ABCD'
      @22,0 say 'Incorrect Counter..Re-enter..'
      && oooo.... two DOS beeps
      ??chr(7)+chr(7)
      && continue the do/while loop
      loop
   endi

   && leaky-boat technique... we got this far, must have had a good value,
   && exit the do/while loop
   exit
endd   && end of the do/while loop

&& new variable "SCntr" = whatever "cntr" is
scntr=cntr

&& reset "x" var back to 1
x=1

&& another do/while loop
do whil .t.
   && more color, and show label to user to enter password
   set colo to n/w
   @22,0
   @22,0 say ;
      'Enter Password              <CR> - Exit                <ESC> - Abort '
   set colo to w/
   @14,20 say 'Enter PASSWORD :-'
   && set console OFF so nobody can see what is being typed...
   set cons off
   @14,38 say ''
   && "Accept" keyboard entry to a variable "ps"
   acce to ps
   && turn console back on to allow seeing typing again
   set cons on

   && I don't know where the "K8", "K4", "K5", etc are... I SUSPECT they
   && are in the user's login table as some sort of mask to compare against
   && "CHR()" is to get ASCII character equivalent based on a numeric value.
   && ex: CHR(32) = ASCII 32 = space character... CHR(65) = "A", CHR(66)="B", etc...
   && so the programmer was building a variable "CPS" by adding a bunch of single
   && characters of the value of "K8" + 9 and getting its ASCII value, then adding
   && the next character, and next until all characters processed into one long string
   cps=chr(k8+9)+chr(k4+7)+chr(k5-31)+chr(k1+13)+chr(k3-19)+;
       chr(k7-35)+chr(k2-27)+chr(k6+1)+chr(k11-6)+chr(k10+6);
       +chr(k12+11)+chr(k9-5)

   && more coloring
   set colo to n/w
   @22,0
   && another exact test
   set exac on
   && if the data entered and "computed string" via "cps" is NOT the same
   && as what I suspect is "ps" a column in the CAN_P table (login table)
   if cps<>ps
      && show message of incorrect password
      @22,0 say 'Incorrect PASSWORD !! Press any key ..'
      && another bell
      ??chr(7)
      && wait for user to hit a key
      read
      && add 1 to the "x" counter for failed attempts / abort 
      x=x+1
      && is user aborting, or exceeded 3 login attempts
      if read()=12 .or. x > 3
         && do the cancel procedure thing again
         do can_011
         && quit the app
         quit
      endi
   else
      && valid password, EXIT the DO/WHILE loop
      exit
   endi
endd   && end of the do/while loop

&& more display status
@22,0
@22,0 say 'Please Wait..'
set exac off

&& "#" is same as <> (not equal to)
&& if the user is NOT "JV"
if user#'JV'
   && more simple boolean check... I assume checking if user is "Active"
   && based on column in the login table
   if .not. (counter=scntr .and. active)
      @22,0 say 'Counter not activated...Access denied..Return to system..'
      && wow... seriously... 4 dos BEEPs, canel process and quit application
      ?? chr(7)+chr(7)+chr(7)+chr(7)
      do can_011
      quit
   endi
endi

&& create var "xr" and preserve whatever the "record number" is in the user table
xr=recn()

&& while still in the login table, try to "LOCATE" for the given condition
&& based on respective variables and their counterpart in the table.
&& HOWEVER, look for value and the record is NOT the one we stored in "xr" above
loca for counter=scntr .and. li .and. recn() <> xr
if found()
   && nag user that the person is already logged in message, 4 bells, cancel, quit app
   @22,0 say 'Counter already Logged-In by User '+user+;
      '..Return to system..'
   ??chr(7)+chr(7)+chr(7)+chr(7)
   do can_011
   quit
endi

&& go back to the originally found record
go xr

&& replace the actual record with status of active = true,
&& lidt (I suspect login date with current date()  (C# DateTime.Now is closest)
&& litm = just the time portion
repl active with .t.,li with .t.,lidt with date(),litm with time()
&& unlock the record
unlo

&& do the "CAN_011" procedure thing
do can_011
&& colors
set colo to w/n,w+/g
&& done with this routine, just return to whoever called it.
retu
于 2012-06-15T11:02:27.180 回答