BASIC

Author Topic: Updating A Program  (Read 6476 times)

MrTAToad

  • Guest
Updating A Program
« on: 2009-Sep-26 »
This is routine for downloading an update to a program, and with Windows, running a batch file to start the update process.  You need DDGui (in addition to the code below) :

Main Routine :
Code: GLBasic [Select]
// ---------------------------------
// Project:
// Start: Sunday, August 09, 2009
// IDE Version: 7.073
TYPE tUpdateProgram
        updateDir$
        tempFile$
        tempINIFile$
        optionsFile$
        webSite$
        webPath$
        updateMessage$
        downloadMessage$
        version%
        platform$
        batchFile$
ENDTYPE

GLOBAL NO_DATA$="NO_DATA"

FUNCTION dummy:
ENDFUNCTION

INLINE
        extern "C" int rename ( const char * oldname, const char * newname );
ENDINLINE

FUNCTION initialiseUpdateProgram%:programName$,webSite$,webPath$,updateProgram AS tUpdateProgram,options$,updateMessage$,downloadMessage$,progVersion$
        updateProgram.updateDir$=PLATFORMINFO$("DOCUMENTS")+"/"+programName$
        IF DOESDIREXIST(updateProgram.updateDir$)=FALSE
                CREATEDIR(updateProgram.updateDir$)
        ENDIF
        updateProgram.updateDir$=updateProgram.updateDir$+"/Update"
        IF DOESDIREXIST(updateProgram.updateDir$)=FALSE
                CREATEDIR(updateProgram.updateDir$)
        ENDIF

        updateProgram.webSite$=webSite$
        updateProgram.webPath$=webPath$
        updateProgram.tempFile$=updateProgram.updateDir$+"/"+"DOWNLOAD.DAT"
        updateProgram.tempINIFile$=updateProgram.updateDir$+"/"+"DOWNLOAD.INI"
        updateProgram.optionsFile$=options$
        updateProgram.platform$=PLATFORMINFO$("")
        updateProgram.updateMessage$=updateMessage$
        updateProgram.downloadMessage$=downloadMessage$
        updateProgram.version%=versionToInt(progVersion$)

        IF updateProgram.platform$="WIN32"
                updateProgram.batchFile$=updateProgram.updateDir$+"/Update.bat"
        ELSE
                updateProgram.batchFile$=""
        ENDIF

        RETURN TRUE
ENDFUNCTION

FUNCTION updateProgram%:updateProgram AS tUpdateProgram
LOCAL proxy$
LOCAL port%
LOCAL messageOfTheDay$
LOCAL SECTION$="DATA"
LOCAL webEntry$
LOCAL webDownloadFiles$[]
LOCAL iniFile$
LOCAL ok%
LOCAL result%
LOCAL fullProg$
LOCAL ok2

        iniFile$="/"+updateProgram.webPath$+"/"+"Update.INI"

        // Make sure the INI file has been deleted
        KILLFILE updateProgram.tempINIFile$
        IF DOESFILEEXIST(updateProgram.tempINIFile$)=TRUE
                RETURN FALSE
        ENDIF

        KILLFILE updateProgram.tempFile$
        IF DOESFILEEXIST(updateProgram.tempFile$)=TRUE
                RETURN FALSE
        ENDIF

        // Download the INI file
        INIOPEN updateProgram.optionsFile$
        proxy$ = INIGET$("server", "proxy")
        port%  = INIGET$("server", "port")
        INIOPEN ""

        IF port%=0 OR proxy$=NO_DATA$
                DEBUG "HERE\n"
                ok%=NETWEBGET(updateProgram.webSite$, iniFile$, 80, updateProgram.tempINIFile$)
        ELSE
                ok%=NETWEBGET(proxy$, "http://"+updateProgram.webSite$+iniFile$, port%, updateProgram.tempINIFile$)
        ENDIF

        DEBUG updateProgram.webSite$+"\n"
        DEBUG iniFile$+"\n"
        DEBUG "OK : "+ok%+"\n"

        IF ok%=FALSE OR DOESFILEEXIST(updateProgram.tempINIFile$)=FALSE
                RETURN FALSE
        ENDIF

        // Display any "message of the day" message
        INIOPEN updateProgram.tempINIFile$
        messageOfTheDay$=INIGET$(SECTION$,"MOTD")
        DEBUG "MOTD:"+messageOfTheDay$+"\n"
        IF messageOfTheDay$<>NO_DATA$ AND LEN(messageOfTheDay$)>0
                // Display any message of the day
                DDgui_msg(messageOfTheDay$,FALSE)
        ENDIF

        // Now to get the information about this platform
        webEntry$=INIGET$(SECTION$,updateProgram.platform$)
        IF webEntry$=NO_DATA$
                DDgui_msg("This platform has no updates availiable for it.  Try again in a few weeks",FALSE)
                RETURN FALSE
        ENDIF
        INIOPEN ""

        // Now we split the entry - the left side is the version, middle is the filename and right is the filename size
        DIM webDownloadFiles$[0]
        IF SPLITSTR(webEntry$,webDownloadFiles$[],",")<>3
                DDgui_msg("Invalid number of entry files",FALSE)
                RETURN FALSE
        ENDIF

        // And delete any previous files
        fullProg$=updateProgram.updateDir$+"/"+webDownloadFiles$[1]
        KILLFILE fullProg$
        IF DOESFILEEXIST(fullProg$)=TRUE
                DDgui_msg("Unable to delete a previous update program",FALSE)
                RETURN FALSE
        ENDIF

        IF versionToInt(webDownloadFiles$[0])>updateProgram.version%
                IF DDgui_msg(updateProgram.updateMessage$,TRUE)
                        // Download the file

                        IF port%=0 OR proxy$=NO_DATA$
                                ok%=NETWEBGET(updateProgram.webSite$, "/"+updateProgram.webPath$+"/"+webDownloadFiles$[1], 80, updateProgram.tempFile$)
                        ELSE
                                ok%=NETWEBGET(proxy$, "http://"+updateProgram.webSite$+"/"+updateProgram.webPath$+"/"+webDownloadFiles$[1], port%, updateProgram.tempFile$)
                        ENDIF

                        IF ok%=FALSE OR DOESFILEEXIST(updateProgram.tempFile$)=FALSE OR isThereA404Error(updateProgram.tempFile$)=TRUE
                                DDgui_msg("File could not be downloaded - it may not exist yet.",FALSE)
                                RETURN FALSE
                        ENDIF

                        // Now we check the CRC32 value
                        result%=calculateCRC32( updateProgram.tempFile$)
                        IF result%=webDownloadFiles$[2]
                                // DDgui_msg("Here",FALSE)
                                // Now we rename the file
                                IF doRename(updateProgram.tempFile$,fullProg$)=0
                                        // If we&#39;re on a Windows machine, then call the batch file
                                        IF updateProgram.batchFile$<>""
                                                SELECT updateProgram.platform$
                                                        CASE    "WIN32"
                                                                                        IF DDgui_msg("Do you want to start the update process now ?",TRUE)=TRUE
                                                                                                SHELLEND CHR$(34)+updateProgram.batchFile$+CHR$(34)+" "+CHR$(34)+fullProg$+CHR$(34)
                                                                                        ENDIF
                                                ENDSELECT
                                        ELSE
                                                DDgui_msg("The update is availiable in your documents folder",FALSE)
                                        ENDIF
                                ELSE
                                        DDgui_msg("Unable to rename the download file",FALSE)
                                ENDIF
                        ELSE
                                DDgui_msg("The file seems to be corrupt - please re-downloading again",FALSE)
                        ENDIF

                        RETURN TRUE
                ENDIF
        ELSE
                DDgui_msg("There are no updates availiable.  Try again in a few weeks",FALSE)
        ENDIF

        RETURN FALSE
ENDFUNCTION

FUNCTION isThereA404Error%:fileName$
LOCAL handle%
LOCAL line$

        handle%=GENFILE()
        IF OPENFILE(handle%,fileName$,1)
                READLINE handle%,line$
                WHILE ENDOFFILE(handle%)=FALSE
                        IF INSTR(line$,"Error 404 - Not found")>=0 OR _
                                (INSTR(line$,"The document name you requested")>=0 AND INSTR(line$,"could not be found on this server")>=0)
                                CLOSEFILE handle%
                                RETURN TRUE
                        ENDIF

                        READLINE handle%,line$
                WEND
        ENDIF

        CLOSEFILE handle%
        RETURN FALSE
ENDFUNCTION

FUNCTION doRename:old$,new$
INLINE
        return rename(old_Str.c_str(),new_Str.c_str());
ENDINLINE
ENDFUNCTION
 

Calculate a CRC32 value for the file (to make sure it downloaded okay)
Code: GLBasic [Select]
// --------------------------------- //
// Project:
// Start: Monday, August 10, 2009
// IDE Version: 7.078
// --------------------------------- //
// Project:
// Start: Monday, August 10, 2009
// IDE Version: 7.078

//! This calculates a CRC-32 value for a file
//\param fileName$ - This is the filename that you want to calculate a CRC value for
//\return - A signed 32-bit CRC value
FUNCTION calculateCRC32%:fileName$
LOCAL channel%  =       1
LOCAL bufferSize%       =       1024
LOCAL d%[];     DIM d%[bufferSize%]
LOCAL amount%
LOCAL crc%
LOCAL loop%
LOCAL length

        crc%=0
        IF DOESFILEEXIST(fileName$)=TRUE
                length=GETFILESIZE(fileName$)
                IF OPENFILE(channel%,fileName$,1)
                        DEBUG "length : "+length+"\n"

                        // Read in bytes
                        FILESEEK channel%,0,0
                        amount%=readInBytes(channel%,d%[],bufferSize%,length)
                        WHILE amount%>0
                                FOR loop%=0 TO amount%-1
                                        crc%=calcCRC32(d%[loop%],crc%)
                                NEXT

                                amount%=readInBytes(channel%,d%[],bufferSize%,length)
                                DEBUG "."
                        WEND

                        crc%=calcCRC32End(crc%)
                        CLOSEFILE channel%
                ELSE
                        DEBUG "Error : "+GETLASTERROR$()+"\n"
                ENDIF
        ENDIF

        RETURN crc%
ENDFUNCTION

@FUNCTION readInBytes%:handle%,d%[],size%,length
LOCAL loop%
LOCAL pos
LOCAL diff

        loop%=0
        WHILE ENDOFFILE(handle%)=FALSE AND loop%<size%
                pos=FILEPOSITION(handle%)
                diff=length-pos
                SELECT diff
                        CASE    1
                                                READUBYTE handle%,d%[loop%]
                        CASE    2
                                                READUWORD handle%,d%[loop%]
                        CASE    3
                                                READUBYTE handle%,d%[loop%]
                                                INC loop%,1
                                                IF loop%<size% AND ENDOFFILE(handle%)=FALSE THEN READUWORD handle%,d%[loop%]
                        CASE    >3
                                                READULONG handle%,d%[loop%]
                ENDSELECT
                INC loop%,1
        WEND

        RETURN loop%
ENDFUNCTION

INLINE
const unsigned long CRC[]={
                0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
                0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
                0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
                0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
                0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
                0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
                0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
                0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
                0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
                0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
                0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
                0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
                0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
                0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
                0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
                0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
                0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
                0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
                0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
                0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
                0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
                0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
                0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
                0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
                0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
                0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
                0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
                0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
                0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
                0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
                0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
                0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
                0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
                0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
                0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
                0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
                0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
                0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
                0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
                0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
                0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
                0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
                0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
                };
ENDINLINE

@FUNCTION calcCRC32%:value%,crc%
INLINE
                return (CRC[(unsigned char) (crc^(unsigned long) value)]^((crc<<8) & 0x00FFFFFF));
ENDINLINE
ENDFUNCTION

@FUNCTION calcCRC32End%:crc%
INLINE
        return (crc^0xFFFFFFFF);
ENDINLINE
ENDFUNCTION
 

Convert a version string to a 32-bit number
Code: GLBasic [Select]
// Convert version information (in the form of x.x.x.x to an integer)
FUNCTION versionToInt%:version$
LOCAL string$[]
LOCAL count%
LOCAL p%
LOCAL total%
LOCAL value%

        DIM string$[0]
        count%=SPLITSTR(version$,string$[],".")
        total%=0
        IF count%>0
                p%=24
                FOR loop%=0 TO MIN(count%,4)-1
                        INC total%,ASL(BAND(string$[loop%],255),p%)
                        DEC p%,8
                NEXT
        ENDIF

        RETURN total%
ENDFUNCTION

And the test program :

Code: GLBasic [Select]
SETSCREEN 640,480,0

GLOBAL updateProg AS tUpdateProgram

DEBUG "Part 1\n"
initialiseUpdateProgram("test","www.miscthings.co.uk","Update",updateProg,"OPTIONS.INI","Do you want to download the update now","Downloading","0.0.0.1")
DEBUG "Part 2\n"
DEBUG "Result : "+updateProgram(updateProg)
DEBUG "Part 3\n"
END

Offline bigsofty

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 2640
    • View Profile
Re: Updating A Program
« Reply #1 on: 2009-Oct-21 »
Missed this one! Good stuff!  :good:
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10723
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Updating A Program
« Reply #2 on: 2009-Oct-21 »
Oh! Very sophisticated! Excellent code.

MrTAToad

  • Guest
Re: Updating A Program
« Reply #3 on: 2009-Oct-23 »
Thanks!

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #4 on: 2009-Nov-12 »
I've been trying to get my CRC32 working for hours now (I didn't find this on my initial search). I don't think it's possible to do it without inline.

Can you please check your code though? I tested the CRC generated for one of my files against 2 different CRC checkers off the internet, and the values generated from your code don't match the others.

From looking at the code and comparing it to pages like http://www.koders.com/c/fid699AFE0A656F0022C9D6B9D1743E697B69CE5815.aspx?s=crc32#L19 or http://www.algorithm-code.com/wiki/CRC32_Algorithm it appears that

1) You are not setting the CRC to 0xFFFFFFFF at the start
2) You are left shifting 8 places instead of right shifting.

I made those changes on my copy and still can't get the numbers to match though.
« Last Edit: 2009-Nov-12 by FutureCow »

Sebastian

  • Guest
Re: Updating A Program
« Reply #5 on: 2009-Nov-12 »
Why use CRC and not MD5?
I wrote an MD5 hash generator in VBA not so long ago (long story short: wasn't satisfied with the Access user control - yes, I have to do the stuff in Access, don't get me startet about THAT - so I wrote my own which uses MD5 hashes for password handling) and if I find the time I might just adapt it for GLBasic. Don't want to promise anything though because my VBA solution uses Windows internal DLLs which would mean no multiplatform support  :(
« Last Edit: 2009-Nov-12 by Sebastian »

MrTAToad

  • Guest
Re: Updating A Program
« Reply #6 on: 2009-Nov-12 »
MD5 was a bit of an overkill.

I'm not surprised the CRC32 value doesn't equal other routines as each does it in a different way.  The link you provided does show probably a better way of doing it, which will be worth looking at.

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #7 on: 2009-Nov-13 »
Okay, this is driving me nuts!  :rant:
I've tried I don't know how many different versions of the algorithm over the past 3 days to try to get my program to return the same results as any CRC32 checker I can find on the internet, and no matter how I modify the code, I can never get a matching CRC value. I have a sneaking suspicion it's being caused by typecasting and signed integer size limits in GLBasic, but I can't see how to get around it without making 99% of the code inline C and having a very GLBasic small wrapper for it. I can't even get that to work as I think that it's every time I read a char from the file and pass that to the program that it's the typecasting of that character that's "breaking" everything else.
I don't know that a GLBasic implementation is possible without an native data type to "unsigned long". I'll happily be proved wrong if anyone wants to try their hand at CRC32 generation. Until then, I'm just going to have to figure out some other solution for verifying 2 files are identical *sigh*

In case anyone does attempt this at a later stage, here's a handy program that generates ~92 types of checksums, including 4 different CRC32 algorithms. http://fsumfe.sourceforge.net/
« Last Edit: 2009-Nov-13 by FutureCow »

MrTAToad

  • Guest
Re: Updating A Program
« Reply #8 on: 2009-Nov-13 »
Without knowing what routine the CRC32 checker uses, you've got no chance in getting the same value.  And I wouldn't worry about it too much either - if the CRC generating routine and the checking routine produce exactly the same value, then you'll be fine.

You will need to use some INLINE (or even REQUIRE), if only for the more compact code.


Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #9 on: 2009-Nov-13 »
There's plenty of information about what Polynomial will give which CRC32 result, matching the code to expected result isn't a problem.

I had another flash of inspiration late today which I tried and I'll test against the various routines again on Monday. Usually - at least for the file I was using - the CRC returned was a negative value. I was trying several different techniques (based on web information and various ideas of my own) to convert that back to an unsigned number, and then to hexadecimal. None of them ever returned the expected CRC string, but maybe I was converting the number wrongly. What I tried late today, and I'll try on the various algorithms again (after this I'm out of ideas!) is to do extract each digit individually taking my conversion out of the picture. i.e.
Code: GLBasic [Select]
for loop = 0 to 7
    array[7-loop]=BAND(CRC32Result,F)
    ASR(CRC32Result,1)
next
That way I have each digit taken from the underlying binary, without having to worry about the things I was trying to figure out, like whether the signed ints were ones complement, twos complement, wrapping around etc. With any luck that will give the correct result with one of the algorithms. I really don't want to let this beat me as it looks like it really should work!!!

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10723
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Updating A Program
« Reply #10 on: 2009-Nov-13 »
do use integers! The CRC32 relies on the overflow of them I think.

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #11 on: 2009-Nov-16 »
Another few hours wasted trying to get an algorithm where the result matches the expected results. GAAAAAAAAA!!!!!!!!

I can get the results to match for the first two characters, any more than that and I get a different result to the "correct" algorithm's results. I haven't worked out what's different between an implementation in GLBasic and one done in straight C. Things I've thought of that it may be that I now have to try to rule out
* Bits not wrapTping where they would in another language when shifts are used
* Endian problems
* Overflow bit?
* 1's complement vs 2's complement
* Typecasting done on one of the binary operations that's not done on one of the others (bAND, bXOR, ASL or ASR)

This is REALLY stressing me now!

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10723
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Updating A Program
« Reply #12 on: 2009-Nov-16 »
Why do you want the exact same results? And what program did you use to get the first crc codes? Maybe we can adapt that source then.

MrTAToad

  • Guest
Re: Updating A Program
« Reply #13 on: 2009-Nov-16 »
Indeed - we need to know what program you are using to "verify" the results.  Hopefully they will have the source code available.

At some point, I'm going to have to create a program to allow users to create VID's for when more people start putting in "Update this program" options  =D

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #14 on: 2009-Nov-17 »
See the next post for a C program which should give a result matching that from a webpage. When I try to recode it in basic, I don't get the same result (using method 5 in my code) the webpage returns.

Unfortunately I don't have any other language compilers, and my C (VB, Python etc) skills aren't what they used to be anyway. So unfortunately I don't have a program I can run in another language to then compare the results with after porting. My alternative is finding code on the net that people say will work, porting that and testing the results against results from CRC generation programs on the net. I know it's not the best solution, but without installing other compilers etc it's the best I can do.

Firstly, to find the results I'm trying to match :

The main programs I'm using to "verify" the results (and I admit that these programs may be the ones giving the wrong results themselves) are
fsum frontend - http://fsumfe.sourceforge.net/. It supports 4 different CRC32 algorithms.
http://www.lammertbies.nl/comm/info/crc-calculation.html
CRC online test http://www.pvlteam.com/doc/crc/testonline.aspx
RapidCRC - http://sourceforge.net/projects/rapidcrc/ - only supports the main CRC32 algorithm
Also trying the same text that I'm putting into the file I'm testing on this page - the result for CRC32b matches the two CRC32 results above - http://www.whatsmyip.org/hash_generator/

All of the above generate a consistant CRC32, so that suggests to me that I should be able to generate that result.
I'm trying to match the results for the algorithm that seems to be the standard (ie. the one specified as CRC32 in the first three links, and as CRC32 in the third link) - also known as CRC-32-IEEE 802.3 (see. http://en.wikipedia.org/wiki/Cyclic_redundancy_check)


My test program - you will see there are 4 different algorithms in there (separate functions for each one). 2-4 give the same results, but the results don't match any of the CRCs generated from the above programs.
Code: GLBasic [Select]
// --------------------------------- //
// Project: checksum3
// Start: Tuesday, November 17, 2009
// IDE Version: 7.170


// GLOBALS
GLOBAL CRC32_Table#[]
DIM CRC32_Table#[256]
GLOBAL CRCValue%                                                // Our CRC32 result



// ------------------------------------------------------------- //
// ---  MAIN  ---
// ------------------------------------------------------------- //

GOSUB CRC32_Create_Lookup_Table                                                                 // Create Lookup table

Generate_CRC32_From_File("c:/temp/a.txt")                                               // Generate results
       
GOSUB Print_Results                                                                                             // Display results
// MAIN




// ------------------------------------------------------------- //
// ---  CRC32_CREATE_LOOKUP_TABLE  ---
// ------------------------------------------------------------- //
SUB CRC32_Create_Lookup_Table:

        RESTORE CRC32_Table_Data                                                                        // Move data pointer to data
       
        FOR ASCIILoop=0 TO 255
                READ CRC32_Table[ASCIILoop]                                                             // Read data into table
        NEXT
ENDSUB // CRC32_CREATELOOKUPTABLE




// ------------------------------------------------------------- //
// ---  GENERATE_CRC32_FROM_FILE  ---
// ------------------------------------------------------------- //
FUNCTION Generate_CRC32_From_File: FileName$

        LOCAL AmountToProcess%
        LOCAL FileHandle,FileOpened, FileSize, FileLocation
        LOCAL Buffer%[]
       
        DIM Buffer%[1024]
       
        CRCValue%=0xFFFFFFFF                                                                                                                    // Set initial value FOR CRC TO $FFFFFFFF

        FileSize=GETFILESIZE(FileName$)                                                                                         // Get the file size of the file to process

        FileOpened=OPENFILE(FileHandle,FileName$,1)                                                                     // Open file for reading
        IF FileOpened=TRUE


// -------------------------------------------------
//      How big is the next chunk of data to process?
                WHILE ENDOFFILE(FileHandle) = FALSE
                        FileLocation=FILEPOSITION(FileHandle)                                                           // Where are we in the file?
                        IF FileSize-FileLocation>1024                                                                           // There&#39;s more than 1kb of the file left so
                                AmountToProcess=1023                                                                                    // Read 1kb
                        ELSE
                                AmountToProcess=FileSize-FileLocation-1                                                 // Process the <1024b of the file that&#39;s left
                        ENDIF
// -------------------------------------------------
// Read in the next chunk (1kb usually) of data into the buffer
                        FOR Loop=0 TO AmountToProcess
                                READUBYTE FileHandle, Buffer[Loop]
                        NEXT

// -------------------------------------------------
// Calculate the CRC32 value
                        DEBUG "."
                        FOR Loop=0 TO AmountToProcess
//                              Calc_CRC32_Method1(Buffer[Loop])                                                                // Calculate CRC32
//                              Calc_CRC32_Method2(Buffer[Loop])                                                                // Calculate CRC32
//                              Calc_CRC32_Method3(Buffer[Loop])                                                                // Calculate CRC32
//                              Calc_CRC32_Method4(Buffer[Loop])                                                                // Calculate CRC32
//                              Calc_CRC32_Method5(Buffer[Loop])                                                                // Calculate CRC32
                        NEXT
                WEND
        ELSE
                STDERR "Couldnt open file " + FileName$ + "\n"
                STDOUT "Couldnt open file " + FileName$ + "\n"
        ENDIF
        CLOSEFILE FileHandle



        CRCValue=BXOR(CRCValue,0xFFFFFFFF)                                                                                      // Return 1s complement


       
        RETURN CRCValue
ENDFUNCTION // GENERATE_CRC32_FROM_FILE




// ------------------------------------------------------------- //
// ---  PRINT_RESULTS  ---
// ------------------------------------------------------------- //
SUB Print_Results:
        LOCAL HexString$="0123456789ABCDEF"                     // String of HEX characters
        LOCAL Result_String$, Temp, RChar$
       
        DEBUG "CRC = " + CRCValue%
        Result_String$=""
        FOR MyLoop=0 TO 7                                                                                                                       // Loop through the 32 bits 8 times - ie. 4 bit chunks
                Temp=BAND(CRCValue%,0xF)                                                                                                        // Return  the last 4 bits
               
                RChar$=MID$(HexString$,Temp,1)                                                                                  // Find their value in HEX
               
                Result_String$=RChar$ + Result_String$                                                                  // Add the HEX value to our Results String
               
                CRCValue%=ASR(CRCValue%,4)                                                                                              // Shift CRC to get the next 4 bits
               
                DEBUG "+"
        NEXT
        DEBUG "\n"+Result_String$+"\n"                                                                                          // Output Result

ENDSUB // PRINT_RESULTS



// ------------------------------------------------------------- //
// ---  CALC_CRC32_METHOD1  ---
// ------------------------------------------------------------- //
FUNCTION Calc_CRC32_Method1: CurrentChar
                        // Algorithm
                        //crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *block++) & 0xFF];
                        LOCAL AA%,BB%,CC%,DD%,EE%
                       
                        AA%=ASR(CRCValue,8)
                        BB%=BAND(AA%,0x00FFFFFF)
                        CC%=BXOR(CRCValue,CurrentChar)
                        DD%=BAND(CC%,0xFF)
                        EE%=CRC32_Table[DD%]
                        CRCValue=BXOR(BB%,EE%)

ENDFUNCTION // CALC_CRC32_METHOD1

// ------------------------------------------------------------- //
// ---  CALC_CRC32_METHOD2  ---
// ------------------------------------------------------------- //
FUNCTION Calc_CRC32_Method2: CurrentChar

                        // Algorithm
                        // crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8)
                        LOCAL AA%,BB%,CC%,DD%,EE%
                       
                        AA%=ASR(CRCValue,8)
                        BB%=BXOR(CRCValue,CurrentChar)
                        CC%=BAND(BB%,0xFF)
                        DD%=CRC32_Table[CC%]
                        CRCValue=BXOR(DD%,AA%)


ENDFUNCTION // CALC_CRC32_METHOD2

// ------------------------------------------------------------- //
// ---  CALC_CRC32_METHOD3  ---
// ------------------------------------------------------------- //
FUNCTION Calc_CRC32_Method3: CurrentChar
                        // Algorithm
                        //    unsigned long tmp, long_c;
                        //    long_c = 0x000000ffL & (unsigned long) c;
                        //    IF ( ! crc_tab32_init ) init_crc32_tab();
                        //    tmp = crc ^ long_c;
                        //    crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];
                        //    RETURN crc;
                        LOCAL AA%,BB%,CC%,DD%,EE%
                       
                        AA%=BAND(0x000000FF ,CurrentChar)
                        BB%=BXOR(CRCValue,AA)
                        DD%=ASR(CRCValue,8)
                        EE%=BAND(BB,0xFF)
                        CRCValue=BXOR(DD,CRC32_Table[EE%])
ENDFUNCTION // CALC_CRC32_METHOD3

// ------------------------------------------------------------- //
// ---  CALC_CRC32_METHOD4  ---
// ------------------------------------------------------------- //
FUNCTION Calc_CRC32_Method4: CurrentChar
                        // Algorithm
                        //              CRCValue=(CRCValue Shr 8) Xor CRC32_table[CurrentByte Xor (CRCValue AND $FF)]
                        LOCAL AA%,BB%,CC%,DD%,EE%
                       
                        AA%=ASR(CRCValue,8)
                        BB%=BAND(CRCValue,0xFF)
                        CC%=BXOR(CurrentChar,BB)
                        DD%=CRC32_Table[CC]
                        CRCValue=BXOR(AA,DD)

ENDFUNCTION // CALC_CRC32_METHOD4




// ------------------------------------------------------------- //
// ---  CALC_CRC32_METHOD5  ---
// ------------------------------------------------------------- //
FUNCTION Calc_CRC32_Method5: CurrentChar%
                        // Algorithm
                        //                  crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];

                        LOCAL AA%,BB%,CC%,DD%,EE%
                       
                        AA%=ASR(CRCValue%,8)
                        BB%=BAND(CurrentChar%,0xFF)
                        CC%=CRC32_Table[BB%]
                        CRCValue=BXOR(AA,CC)

ENDFUNCTION // CALC_CRC32_METHOD5

// ------------------------------------------------------------- //
// ---  DATA_BLOCK  ---
// ------------------------------------------------------------- //

STARTDATA CRC32_Table_Data:
DATA 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f
DATA 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988
DATA 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2
DATA 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7
DATA 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9
DATA 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172
DATA 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c
DATA 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59
DATA 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423
DATA 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924
DATA 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106
DATA 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433
DATA 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d
DATA 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e
DATA 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950
DATA 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65
DATA 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7
DATA 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0
DATA 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa
DATA 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f
DATA 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81
DATA 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a
DATA 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84
DATA 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1
DATA 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb
DATA 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc
DATA 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e
DATA 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b
DATA 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55
DATA 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236
DATA 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28
DATA 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d
DATA 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f
DATA 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38
DATA 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242
DATA 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777
DATA 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69
DATA 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2
DATA 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc
DATA 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9
DATA 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693
DATA 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94
DATA 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
ENDDATA

Some of the many source code pages I've looked at
The start of this forum post.
http://www.glbasic.com/forum/index.php?topic=2788.msg20519#msg20519
http://www.networkdls.com/Software.Asp?Review=22
http://www.koders.com/c/fid699AFE0A656F0022C9D6B9D1743E697B69CE5815.aspx?s=crc32#L19
http://www.hackersdelight.org/crc.pdf (Method 1)
http://www.cl.cam.ac.uk/research/srg/bluebook/21/crc/node6.html#SECTION00060000000000000000
« Last Edit: 2009-Nov-17 by FutureCow »