CLOUD: Update StorageWizardDialog's code check

Now the code contains its own crc16 in it, plus the way checksum is
calculated has changed.

Some online tool calls this exact way of calculating crc16
"CRC16_CCITT_FALSE".
This commit is contained in:
Alexander Tkachev 2016-06-15 13:31:59 +06:00
parent c1ffb09fb0
commit a83e91e1ca
2 changed files with 35 additions and 94 deletions

View File

@ -88,18 +88,28 @@ void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
}
}
}
if (message.size() > 0) {
Common::String messageTemplate;
if (CODE_FIELDS - correctFields == 1) messageTemplate = _("Field %s has a mistake in it.");
else messageTemplate = _("Fields %s have mistakes in them.");
message = Common::String::format(messageTemplate.c_str(), message.c_str());
}
bool ok = false;
if (correctFields == CODE_FIELDS && code.size() > 0) {
message = Common::String::format(_("CRC-32 for this code is: %x"), crc32(code));
_connectWidget->setEnabled(true);
} else {
_connectWidget->setEnabled(false);
//the last 3 chars must be an encoded crc16
if (code.size() > 3) {
uint32 size = code.size();
uint32 gotcrc = decodeHashchar(code[size-3]) | (decodeHashchar(code[size-2]) << 6) | (decodeHashchar(code[size-1]) << 12);
code.erase(size - 3);
uint32 crc = crc16(code);
ok = (crc == gotcrc);
}
if (ok) message = _("All OK!");
else message = _("Invalid code");
}
_connectWidget->setEnabled(ok);
_messageWidget->setLabel(message);
break;
}
@ -111,6 +121,7 @@ void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
code += subcode;
code.deleteLastChar();
}
code.erase(code.size() - 3);
CloudMan.connectStorage(_storageId, code);
setResult(1);
close();
@ -121,101 +132,31 @@ void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
}
}
int StorageWizardDialog::calculate(char b) {
int r = 0;
for (; b; b = b >> 1)
r += b & 1;
return r;
int StorageWizardDialog::decodeHashchar(char c) {
const char HASHCHARS[65] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ?!";
for (uint32 i = 0; i < 64; ++i)
if (c == HASHCHARS[i])
return i;
return -1;
}
bool StorageWizardDialog::correctChecksum(Common::String s) {
const char HASHCHARS[65] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ?!";
char c = s.lastChar();
int providedChecksum = -1;
for (uint32 i = 0; i < 64; ++i)
if (c == HASHCHARS[i]) {
providedChecksum = i;
break;
}
int calculatedChecksum = 0;
int providedChecksum = decodeHashchar(s.lastChar());
int calculatedChecksum = 0x2A;
for (uint32 i = 0; i < s.size()-1; ++i) {
calculatedChecksum = (calculatedChecksum << 1) | (calculate(s[i]) & 1);
calculatedChecksum = calculatedChecksum ^ s[i];
}
return providedChecksum == calculatedChecksum; //we can use compare bits to determine which characters are wrong
return providedChecksum == (calculatedChecksum % 64);
}
const uint32 Crc32Table[256] = {
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
};
uint32 StorageWizardDialog::crc32(Common::String s) {
uint32 crc = 0xFFFFFFFF;
for (uint32 i = 0; i < s.size(); ++i)
crc = (crc >> 8) ^ Crc32Table[(crc ^ s[i]) & 0xFF];
return crc ^ 0xFFFFFFFF;
uint32 StorageWizardDialog::crc16(Common::String s) { //"CRC16_CCITT_FALSE"
uint32 crc = 0xFFFF, x;
for (uint32 i = 0; i < s.size(); ++i) {
x = ((crc >> 8) ^ s[i]) & 0xFF;
x ^= x >> 4;
crc = ((crc << 8) ^ (x << 12) ^ (x << 5) ^ x) & 0xFFFF;
}
return crc;
}
} // End of namespace GUI

View File

@ -40,9 +40,9 @@ class StorageWizardDialog : public Dialog {
StaticTextWidget *_messageWidget;
ButtonWidget *_connectWidget;
int calculate(char b);
int decodeHashchar(char c);
bool correctChecksum(Common::String s);
uint32 crc32(Common::String s);
uint32 crc16(Common::String s);
public:
StorageWizardDialog(uint32 storageId);