Page 1 of 5

128 - Software CRC

Posted: Mon May 06, 2002 9:52 am
by Revenger
I don't know why I get Runtime Error... I tested my program on many tests but with no results. Please, help me.

Here is my code

[pascal](* Software CRC *)

Program p128;

Const g = 34943;

Var Ch : Char;
S : String;
last,i,j : integer;

begin
While True Do begin
last:=0;
Read(Ch);
if Ch='#' then Break;
While (Not Eof(InPut)) And (Not Eoln(InPut)) do begin
last:=last*256+Ord(Ch);
last:=last mod g;
Read(Ch);
end;
last:=last*256+Ord(Ch);
last:=last mod g;
if Eoln(InPut) then Readln;
for i:=1 to 2 do last:=last*256 mod g;
if last>0 then last:=g-last;
S:='';
for i:=1 to 4 do begin
if i=3 then S:=' '+S;
j:=last mod 16;
last:=last div 16;
if j<10 then S:=Chr(Ord('0')+j)+S else S:=Chr(Ord('A')+j-10)+S;
end;
Writeln(S);
end;
end.[/pascal]

???

Posted: Sat Jun 15, 2002 5:42 am
by junjieliang
Could someone explain this problem to me, with reference to the sample input? Thanks.

128 Software CRC

Posted: Sun Feb 02, 2003 2:20 pm
by epsilon0
is there any trick in this problem?

end of lines are \r\n right?

i don't get it.

[c]#include <stdio.h>
#include <stdlib.h>

#define GGG 34943

void print(int val)
{
printf("%02X %02X\n",val>>8, val - ((val >> 8) <<
8));
}

char solve()
{
char c;
int reminder = 0;
int checksum;
scanf("%c",&c);
if (c == '\r' || c == '\n')
scanf("%c",&c);
while (1)
{
if (c == '#') return 0;
if (c == '\r' || c == '\n') break;
reminder =((reminder * 256) + (int)c) % GGG;
scanf("%c",&c);
}
reminder = (reminder * 256 * 256) % GGG;
checksum = (reminder == 0) ? 0 : GGG - reminder;
print(checksum);
return 1;
}

int main()
{
while (solve());
return EXIT_SUCCESS;
}[/c]

Posted: Sun Feb 02, 2003 3:05 pm
by nghiank
test

Posted: Mon Feb 03, 2003 11:49 am
by Ivan Golubev
Do not skip blank lines. And there no "\r"'s in unix text files (but it doesn't really matters). Use gets() to read input and everything will be fine.

Posted: Mon Feb 03, 2003 12:55 pm
by epsilon0
end of lines seem to be \r\n on my linux box.
removing the \r gives different results. (correct ones).

Posted: Tue Feb 04, 2003 8:49 am
by nghiank
Hi Epsilon0!
My code always get Wa. Why don't you give me the test?
I don't ignore blank spaces, but My code still get Wa.
Test:
Input:
JDJDJDJDJDJ

JDJDJDJ
What's your output?

Posted: Tue Feb 04, 2003 10:01 am
by little joey
If I feed the text op nghiank's Pascal source (as listed above) with an extra line containing '#' at the end to my accepted program, I get:

Code: Select all

60 D1  38 56  6A C3  7F 54  87 43  7C D3  26 FA  77 B2  00 00
46 74  0B F1  71 99  03 38  41 00  57 51  5B E7  0D 42  4B 7A
4D 8A  3F B0  4A BC  45 5D  00 00  4B A3  06 A9  03 38  10 3F
0D 42  7E 42  45 81  4A BC  47 D9  57 79  64 92  1A 73  44 9F
53 C5  47 78  15 D3  7E 23  7E A0  01 BD  45 5D  00 00  47 15
03 38  1E E7  0D 42  7F 55  1E 6A  16 16  3C 98  15 7A  33 4F
23 47  7C 24  66 20  05 A2  4A BC  45 5D  00 00  05 CB  86 E5
32 B4
Most of the end-of-lines are replaced by double spaces to save space in this message.
Use it as a test.

Posted: Wed Feb 05, 2003 3:48 pm
by nghiank
kkk

Posted: Wed Feb 05, 2003 4:07 pm
by nghiank
test

Posted: Wed Feb 05, 2003 8:05 pm
by little joey
:D

I get WA on 128 here too

Posted: Thu Feb 13, 2003 8:17 am
by debr
I've checked against all posted patterns, and I haven't found any problems. What gives here?

[cpp]
#include <iostream>
#include <stdio.h>
using std::cin;

int main () {
unsigned char buffer[1028];
unsigned int modulus = 34943;
while(!cin.eof()) {
cin.getline((char *) buffer,1028,'\n');
if (buffer[0] == '#') { break; }
unsigned int crc=0;
unsigned char *ptr = buffer;
while(*ptr != '\n' && *ptr != '\r') {
crc = 256 * crc + (unsigned int) *ptr;
ptr++; crc %= modulus;
}
// last two byte stuff
crc *= 256; crc %= modulus; crc *= 256; crc %= modulus;
if (crc > 0) { crc = modulus-crc; }
unsigned int msb = crc / 256 ;
unsigned int lsb = crc % 256 ;
printf("%02X %02X\n",msb,lsb);
}
return 0;
}
[/cpp]

128 time limit exceed

Posted: Wed Jun 04, 2003 2:48 pm
by boatfish
why??
[cpp]#include<iostream>
#include<string>
using namespace std;

string output(int a){
string result,no="0123456789ABCDEF";
for(int j=1;j<=4;a=a/16,j++){
int i=a%16;
result=no+result;
}
return result.substr(0,2)+" "+result.substr(2);
}

int main(){
string buffer;
int i;
while(true){
string buffer;
char bu;
while(cin.get(bu)){
if(bu=='\n')
break;
buffer=buffer+bu;
}
if(buffer[0]=='#')
return 0;
int length=buffer.length(),base=0,checksum;
if(length==0){
cout<<"00 00"<<endl;
continue;
}
for(i=0;i<length;i++)
base=(base*256+buffer)%34943;
base=(base*256*256)%34943;
checksum= (base==0?base:(34943-base));
cout<<output(checksum)<<endl;
}
return 0;
}[/cpp][/c]

Upper case

Posted: Tue Jun 10, 2003 7:46 pm
by Experimenter
I was just wondering if the reason of getting WA might be a printing in a hex format in a low case?
I am solving 128 problem and there you need to output two bytes. that's how I do it.
[cpp]
cout.fill('0');
cout<<hex<<setw(2)<<nHigherByteCRC<<" ";
cout<<hex<<setw(2)<<nLowerByteCRC <<" "<<endl;
[/cpp]
Does anybody know if there is any simplier way to do it and besides to make cout ouput everything in uppercase. [/cpp][/b]

128

Posted: Tue Jun 10, 2003 9:33 pm
by Experimenter
Hi, guys.
I was struggling with 128 problem and it seems to work, but I still cannot get AC. the asnwer is WA. my cpp code is below. maybe somebody can give me a hint? or at least some input and output for the input to try?
[cpp]
#include <fstream>
#include <string>
#include <iostream>
#include <iomanip>
#include <memory>
#include <stdio.h>

using namespace std;

typedef unsigned char BOOL;

const BOOL FALSE = 0;
const BOOL TRUE = 1;

int main();
long Reminder(char *chMessage,int nDWLen,long lnGenerator);

int main()
{

const long lnGenerator = 34943;
const int nAddLetters = 4;
const int nDataLen = 1024 + nAddLetters + 2;// 1024 - for the data,
// 2 - for Redundancy Error
// 4 - for correcting the data length (make even)

long r;
long CRC;
int tAdd,tBegin,rem;
int nLowerByteCRC;
int nHigherByteCRC;

char chData[nDataLen];
char *chMessage = NULL;
BOOL fl = TRUE;
int nReadLen = 0;
int nMessageLen= 0;

// ifstream fin("input.txt");

while(fl)
{

memset((void *)chData,0,(size_t)(nDataLen*sizeof(chData[0])));
//fin.getline(&chData[nAddLetters],nDataLen);
cin.getline(&chData[nAddLetters],nDataLen,'\n');
nReadLen = strlen(&chData[nAddLetters]);


if('#' == chData [nAddLetters])
{
fl = FALSE;
}
else
{
rem = (nReadLen + 2)% 4;
tAdd = (!rem) ? 0 : (4 - rem); // number of letters to add
tBegin = (!rem) ? 4 : rem ; // where the message will start
nMessageLen = nReadLen + 2 + tAdd ; // message length
chMessage = (char *)&chData[tBegin];

// calculate CRC

r = Reminder(chMessage,(nMessageLen>>2),lnGenerator);
CRC = (0 == r) ? 0 : (lnGenerator - r);

nHigherByteCRC = CRC>>8;
nLowerByteCRC = CRC & (int)(0x00FF);

//cout.fill('0');
//cout.setf(ios_base::hex,ios_base::showbase);
//cout.setf(1,ios_base::uppercase);
//cout<<hex<<setw(2)<<uppercase<<nHigherByteCRC<<" ";
//cout<<hex<<setw(2)<<uppercase<<nLowerByteCRC <<" "<<endl;
printf("%02X %02X\n",nHigherByteCRC,nLowerByteCRC);
}


}


return (0);
}

long Reminder(char *chMessage,int nDWLen,long lnGenerator)
{
long r,t;
int i;

const int nIter = 2*nDWLen - 1;
r = (int)chMessage[0];
r<<= 8;
r |= chMessage[1];


for(i = 1; i <= nIter; i++)
{
t = r;
t<<= 16;
t |= (((int)chMessage[i<<1])<<8 ) | ((int)chMessage[i*2 + 1]);
r = t % lnGenerator;
}

return r;
}
[/cpp]