Generalized Crc32 implementation so it can be used for LG (TLL), Panasonic (.bin and .db) and Sony (sdb.xml)

This commit is contained in:
hbeham
2019-07-20 02:08:51 +02:00
parent 8e6d32e557
commit 1e26ef9cd4
4 changed files with 68 additions and 320 deletions

View File

@@ -1,45 +1,92 @@
namespace ChanSort.Api
{
public static class Crc32
public class Crc32
{
private const uint CrcMask = 0xFFFFFFFF;
private const uint CrcPoly = 0xEDB88320;
// This implementation is MSB-first based, using left-shift operators and a polynomial of 0x04C11DB7
// To get the same CRC32 values that an LSB-first implementation with polynomial 0xEDB88320 would produce,
// all bits in the input bytes and the resulting crc need to be reversed (msb to lsb)
private static readonly uint[] crc32Table;
private const uint CrcMask = 0xFFFFFFFF;
private const uint CrcPoly = 0x04C11DB7;
public static Crc32 Normal = new Crc32(true);
public static Crc32 Reversed = new Crc32(false);
private static readonly byte[] BitReversedBytes = new byte[256];
private readonly uint[] crc32Table;
private readonly bool msbFirst;
#region static initializers
static Crc32()
{
crc32Table = InitCrc32Table();
InitCrc32Table();
InitReversedBitOrderTable();
}
private static void InitReversedBitOrderTable()
{
for (int i = 0; i < 256; i++)
{
byte v = 0;
for (int j = 0, m = i; j < 8; j++, m >>= 1)
{
v <<= 1;
if ((m & 1) != 0)
v |= 0x01;
}
BitReversedBytes[i] = v;
}
}
#region InitCrc32Table()
private static uint[] InitCrc32Table()
{
var crcTable = new uint[256];
var poly = CrcPoly;
for (uint i = 0; i < 256; i++)
{
uint r = i;
for (uint j = 8; j > 0; j--)
uint r = i << 24;
for (uint j = 0; j < 8; j++)
{
if ((r & 1) == 1)
r = ((r >> 1) ^ CrcPoly);
if ((r & 0x80000000) != 0)
r = (r << 1) ^ poly;
else
r >>= 1;
r <<= 1;
}
crcTable[i] = r;
}
return crcTable;
}
#endregion
/// <param name="msbFirst">true for using the "left shift" MSB-first algorithm with polynomial 0x04C11Db7. false to use "right shift" with polynomial 0xEDB883320</param>
public Crc32(bool msbFirst = true)
{
this.msbFirst = msbFirst;
crc32Table = InitCrc32Table();
}
#region CalcCrc32()
public static uint CalcCrc32(byte[] block, int start, int length)
public uint CalcCrc32(byte[] data, int start, int length)
{
uint crc32 = CrcMask;
for (int i = 0; i < length; i++)
crc32 = crc32Table[(crc32 & 0xff) ^ block[start + i]] ^ (crc32 >> 8);
return crc32;
{
var b = data[start + i];
if (!this.msbFirst)
b = BitReversedBytes[b];
crc32 = (crc32 << 8) ^ crc32Table[((crc32 >> 24) ^ b) & 0xFF];
}
if (this.msbFirst)
return crc32;
// reverse all bits to make MSB <-> LSB
return (uint) BitReversedBytes[crc32 >> 24] | ((uint) BitReversedBytes[(crc32 >> 16) & 0xFF] << 8) | ((uint) BitReversedBytes[(crc32 >> 8) & 0xFF] << 16) | ((uint) BitReversedBytes[crc32 & 0xFF] << 24);
}
#endregion
@@ -52,7 +99,7 @@
{
if (crc32 == checksum)
return i;
crc32 = crc32Table[(crc32 & 0xff) ^ block[i]] ^ (crc32 >> 8);
crc32 = (crc32 >> 8) ^ crc32Table[(crc32 >> 24) ^ block[i]];
}
return 0;
}

View File

@@ -426,7 +426,7 @@ namespace ChanSort.Loader.LG
this.dvbsSubblockCrcOffset[i] = off;
int subblockLength = satConfig.dvbsSubblockLength[i];
uint fileCrc = BitConverter.ToUInt32(fileContent, off);
uint calcCrc = Crc32.CalcCrc32(fileContent, off + 4, subblockLength);
uint calcCrc = Crc32.Reversed.CalcCrc32(fileContent, off + 4, subblockLength);
if (fileCrc != calcCrc)
throw new FileLoadException(string.Format(ERR_wrongChecksum, fileCrc, calcCrc));
off += 4 + subblockLength;
@@ -1008,7 +1008,7 @@ namespace ChanSort.Loader.LG
{
for (int i = 0; i < this.dvbsSubblockCrcOffset.Length; i++)
{
uint crc32 = Crc32.CalcCrc32(fileContent, this.dvbsSubblockCrcOffset[i] + 4, satConfig.dvbsSubblockLength[i]);
uint crc32 = Crc32.Reversed.CalcCrc32(fileContent, this.dvbsSubblockCrcOffset[i] + 4, satConfig.dvbsSubblockLength[i]);
var bytes = BitConverter.GetBytes(crc32);
for (int j = 0; j < bytes.Length; j++)
fileContent[this.dvbsSubblockCrcOffset[i] + j] = bytes[j];

View File

@@ -12,7 +12,6 @@ namespace ChanSort.Loader.Panasonic
class Serializer : SerializerBase
{
private const string ERR_FileFormatOrEncryption = "File uses an unknown format or encryption";
private static readonly int[] headerCypherTable;
private readonly ChannelList avbtChannels = new ChannelList(SignalSource.AnalogT | SignalSource.Tv | SignalSource.Radio, "Analog Antenna");
private readonly ChannelList avbcChannels = new ChannelList(SignalSource.AnalogC | SignalSource.Tv | SignalSource.Radio, "Analog Cable");
private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbT | SignalSource.Tv | SignalSource.Radio, "DVB-T");
@@ -36,272 +35,6 @@ namespace ChanSort.Loader.Panasonic
Unknown
}
#region static ctor / headerCypherTable
static Serializer()
{
headerCypherTable = new[]
{
0,
79764919,
159529838,
222504665,
319059676,
398814059,
445009330,
507990021,
638119352,
583659535,
797628118,
726387553,
890018660,
835552979,
1015980042,
944750013,
1276238704,
1221641927,
1167319070,
1095957929,
1595256236,
1540665371,
1452775106,
1381403509,
1780037320,
1859660671,
1671105958,
1733955601,
2031960084,
2111593891,
1889500026,
1952343757,
-1742489888,
-1662866601,
-1851683442,
-1788833735,
-1960329156,
-1880695413,
-2103051438,
-2040207643,
-1104454824,
-1159051537,
-1213636554,
-1284997759,
-1389417084,
-1444007885,
-1532160278,
-1603531939,
-734892656,
-789352409,
-575645954,
-646886583,
-952755380,
-1007220997,
-827056094,
-898286187,
-231047128,
-151282273,
-71779514,
-8804623,
-515967244,
-436212925,
-390279782,
-327299027,
881225847,
809987520,
1023691545,
969234094,
662832811,
591600412,
771767749,
717299826,
311336399,
374308984,
453813921,
533576470,
25881363,
88864420,
134795389,
214552010,
2023205639,
2086057648,
1897238633,
1976864222,
1804852699,
1867694188,
1645340341,
1724971778,
1587496639,
1516133128,
1461550545,
1406951526,
1302016099,
1230646740,
1142491917,
1087903418,
-1398421865,
-1469785312,
-1524105735,
-1578704818,
-1079922613,
-1151291908,
-1239184603,
-1293773166,
-1968362705,
-1905510760,
-2094067647,
-2014441994,
-1716953613,
-1654112188,
-1876203875,
-1796572374,
-525066777,
-462094256,
-382327159,
-302564546,
-206542021,
-143559028,
-97365931,
-17609246,
-960696225,
-1031934488,
-817968335,
-872425850,
-709327229,
-780559564,
-600130067,
-654598054,
1762451694,
1842216281,
1619975040,
1682949687,
2047383090,
2127137669,
1938468188,
2001449195,
1325665622,
1271206113,
1183200824,
1111960463,
1543535498,
1489069629,
1434599652,
1363369299,
622672798,
568075817,
748617968,
677256519,
907627842,
853037301,
1067152940,
995781531,
51762726,
131386257,
177728840,
240578815,
269590778,
349224269,
429104020,
491947555,
-248556018,
-168932423,
-122852000,
-60002089,
-500490030,
-420856475,
-341238852,
-278395381,
-685261898,
-739858943,
-559578920,
-630940305,
-1004286614,
-1058877219,
-845023740,
-916395085,
-1119974018,
-1174433591,
-1262701040,
-1333941337,
-1371866206,
-1426332139,
-1481064244,
-1552294533,
-1690935098,
-1611170447,
-1833673816,
-1770699233,
-2009983462,
-1930228819,
-2119160460,
-2056179517,
1569362073,
1498123566,
1409854455,
1355396672,
1317987909,
1246755826,
1192025387,
1137557660,
2072149281,
2135122070,
1912620623,
1992383480,
1753615357,
1816598090,
1627664531,
1707420964,
295390185,
358241886,
404320391,
483945776,
43990325,
106832002,
186451547,
266083308,
932423249,
861060070,
1041341759,
986742920,
613929101,
542559546,
756411363,
701822548,
-978770311,
-1050133554,
-869589737,
-924188512,
-693284699,
-764654318,
-550540341,
-605129092,
-475935807,
-413084042,
-366743377,
-287118056,
-257573603,
-194731862,
-114850189,
-35218492,
-1984365303,
-1921392450,
-2143631769,
-2063868976,
-1698919467,
-1635936670,
-1824608069,
-1744851700,
-1347415887,
-1418654458,
-1506661409,
-1561119128,
-1129027987,
-1200260134,
-1254728445,
-1309196108
};
}
#endregion
#region ctor()
public Serializer(string inputFile) : base(inputFile)
{
@@ -461,16 +194,12 @@ namespace ChanSort.Loader.Panasonic
#endregion
#region CalcChecksum()
private uint CalcChecksum(byte[] data, int length)
{
uint v = 0xffffffff;
for (int i = 0; i < length; i++)
{
byte b = data[i];
v = (v << 8) ^ (uint)headerCypherTable[((v >> 24) ^ b) & 0xFF];
}
return v;
return Crc32.Normal.CalcCrc32(data, 0, length);
}
#endregion
#region CleanTempFile()

View File

@@ -38,28 +38,6 @@ namespace ChanSort.Loader.Sony
private readonly Dictionary<ChannelList, ChannelListNodes> channeListNodes = new Dictionary<ChannelList, ChannelListNodes>();
#region Crc32Table
private static readonly uint[] Crc32Table =
{
0, 79764919, 159529838, 222504665, 319059676, 398814059, 445009330, 507990021, 638119352, 583659535, 797628118, 726387553, 890018660, 835552979, 1015980042, 944750013,
1276238704, 1221641927, 1167319070, 1095957929, 1595256236, 1540665371, 1452775106, 1381403509, 1780037320, 1859660671, 1671105958, 1733955601, 2031960084, 2111593891, 1889500026, 1952343757,
2552477408, 2632100695, 2443283854, 2506133561, 2334638140, 2414271883, 2191915858, 2254759653, 3190512472, 3135915759, 3081330742, 3009969537, 2905550212, 2850959411, 2762807018, 2691435357,
3560074640, 3505614887, 3719321342, 3648080713, 3342211916, 3287746299, 3467911202, 3396681109, 4063920168, 4143685023, 4223187782, 4286162673, 3779000052, 3858754371, 3904687514, 3967668269,
881225847, 809987520, 1023691545, 969234094, 662832811, 591600412, 771767749, 717299826, 311336399, 374308984, 453813921, 533576470, 25881363, 88864420, 134795389, 214552010,
2023205639, 2086057648, 1897238633, 1976864222, 1804852699, 1867694188, 1645340341, 1724971778, 1587496639, 1516133128, 1461550545, 1406951526, 1302016099, 1230646740, 1142491917, 1087903418,
2896545431, 2825181984, 2770861561, 2716262478, 3215044683, 3143675388, 3055782693, 3001194130, 2326604591, 2389456536, 2200899649, 2280525302, 2578013683, 2640855108, 2418763421, 2498394922,
3769900519, 3832873040, 3912640137, 3992402750, 4088425275, 4151408268, 4197601365, 4277358050, 3334271071, 3263032808, 3476998961, 3422541446, 3585640067, 3514407732, 3694837229, 3640369242,
1762451694, 1842216281, 1619975040, 1682949687, 2047383090, 2127137669, 1938468188, 2001449195, 1325665622, 1271206113, 1183200824, 1111960463, 1543535498, 1489069629, 1434599652, 1363369299,
622672798, 568075817, 748617968, 677256519, 907627842, 853037301, 1067152940, 995781531, 51762726, 131386257, 177728840, 240578815, 269590778, 349224269, 429104020, 491947555,
4046411278, 4126034873, 4172115296, 4234965207, 3794477266, 3874110821, 3953728444, 4016571915, 3609705398, 3555108353, 3735388376, 3664026991, 3290680682, 3236090077, 3449943556, 3378572211,
3174993278, 3120533705, 3032266256, 2961025959, 2923101090, 2868635157, 2813903052, 2742672763, 2604032198, 2683796849, 2461293480, 2524268063, 2284983834, 2364738477, 2175806836, 2238787779,
1569362073, 1498123566, 1409854455, 1355396672, 1317987909, 1246755826, 1192025387, 1137557660, 2072149281, 2135122070, 1912620623, 1992383480, 1753615357, 1816598090, 1627664531, 1707420964,
295390185, 358241886, 404320391, 483945776, 43990325, 106832002, 186451547, 266083308, 932423249, 861060070, 1041341759, 986742920, 613929101, 542559546, 756411363, 701822548,
3316196985, 3244833742, 3425377559, 3370778784, 3601682597, 3530312978, 3744426955, 3689838204, 3819031489, 3881883254, 3928223919, 4007849240, 4037393693, 4100235434, 4180117107, 4259748804,
2310601993, 2373574846, 2151335527, 2231098320, 2596047829, 2659030626, 2470359227, 2550115596, 2947551409, 2876312838, 2788305887, 2733848168, 3165939309, 3094707162, 3040238851, 2985771188
};
#endregion
#region ctor()
public Serializer(string inputFile) : base(inputFile)
@@ -483,13 +461,7 @@ namespace ChanSort.Loader.Sony
end = data.Length;
}
uint crc = 0xFFFFFFFF;
for (int i = start; i < end; i++)
{
var b = data[i];
crc = (crc << 8) ^ Crc32Table[b ^ (crc >> 24)];
}
return ~crc;
return ~Crc32.Normal.CalcCrc32(data, start, end - start);
}
#endregion