Common Data Types (Burnout Paradise)/CgsID Functions
This page lists C++ functions that can encode and decode the compressed strings Criterion uses. Though these functions are unofficial, the results are known to be accurate.
In the future, it may be worth simplifying the decompiled CgsIDCompress()
, CgsIDUnCompress()
, and CgsIDConvertToString()
functions found in the DWARF symbols of certain development builds and listing them here instead.
Encode
#include <cstdint>
#include <iostream>
#include <string>
uint64_t encode(std::string id) {
if (id.length() < 1) {
std::cerr << "Error: No input to encode";
return 0;
}
else if (id.length() > 12) {
std::cerr << "Error: Input must be 12 characters or less";
return 0;
}
uint64_t encoded = 0;
if (id.length() < 13 && id.length() > 0) {
for (int i = 0; i < 12; ++i) {
char chr = 0;
if (i < id.length())
chr = id[i];
if (chr == 0)
chr = 32;
if (chr == 95)
encoded = encoded * 40 + 39;
else if (chr >= 65)
encoded = encoded * 40 + (chr - 52);
else if (chr >= 48)
encoded = encoded * 40 + (chr - 45);
else if (chr >= 47)
encoded = encoded * 40 + 2;
else if (chr >= 45)
encoded = encoded * 40 + 1;
else
encoded *= 40;
}
}
return encoded;
}
Decode
Note that in Criterion's functions, trailing whitespace removal is done in CgsIDConvertToString()
.
#include <cstdint>
#include <string>
std::string decode(uint64_t id) {
if (!id) // No data
return "Invalid ID";
std::string decoded = "";
for (int i = 0; i < 12; ++i) {
uint64_t mod = id % 40;
if (mod == 39)
decoded.insert(0, 1, '_');
else if (mod >= 13)
decoded.insert(0, 1, mod + 52);
else if (mod >= 3)
decoded.insert(0, 1, mod + 45);
else if (mod >= 2)
decoded.insert(0, 1, '/');
else {
mod = (mod - 1) & 32;
decoded.insert(0, 1, mod);
}
id /= 40;
}
// Remove trailing spaces
for (int i = 11; i >= 0; --i) {
if (decoded.back() == 32)
decoded.pop_back();
else
break;
}
return decoded;
}