Files
Fonepay-Unity/Packages/com.voidbotz.fonepayunity/Runtime/QR/FonepayQRGenerator.Codewords.cs
Savya Bikram Shah 2223b2d3ae initital push
2026-05-07 14:18:36 +05:45

63 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
namespace Darkmatter.Fonepay
{
public static partial class FonepayQRGenerator
{
static byte[] BuildCodewords(byte[] data, int version, EccLevel ecc,
(int total, int ecPerBlock, int blocks) ecBlocks)
{
var bits = new List<bool>();
bits.AddRange(new[] { false, true, false, false }); // byte mode
int len = data.Length;
for (int i = 7; i >= 0; i--) bits.Add(((len >> i) & 1) == 1);
foreach (byte b in data)
for (int i = 7; i >= 0; i--)
bits.Add(((b >> i) & 1) == 1);
int dcBytes = DataCodewords(version, ecc);
int targetBits = dcBytes * 8;
for (int i = 0; i < 4 && bits.Count < targetBits; i++) bits.Add(false);
while (bits.Count % 8 != 0) bits.Add(false);
bool[] padA = { true, true, true, false, true, true, false, false };
bool[] padB = { false, false, false, true, false, false, false, true };
int pi = 0;
while (bits.Count < targetBits)
{
bits.AddRange(pi % 2 == 0 ? padA : padB);
pi++;
}
byte[] dc = new byte[dcBytes];
for (int i = 0; i < dcBytes; i++)
for (int b = 0; b < 8; b++)
if (bits[i * 8 + b])
dc[i] |= (byte)(1 << (7 - b));
int blocks = ecBlocks.blocks;
int ecPer = ecBlocks.ecPerBlock;
int blockSize = dcBytes / blocks;
byte[][] dcBlocks = new byte[blocks][];
byte[][] ecBlocksArr = new byte[blocks][];
for (int i = 0; i < blocks; i++)
{
dcBlocks[i] = new byte[blockSize];
Array.Copy(dc, i * blockSize, dcBlocks[i], 0, blockSize);
ecBlocksArr[i] = ReedSolomon(dcBlocks[i], ecPer);
}
var result = new List<byte>();
for (int i = 0; i < blockSize; i++)
for (int b = 0; b < blocks; b++)
result.Add(dcBlocks[b][i]);
for (int i = 0; i < ecPer; i++)
for (int b = 0; b < blocks; b++)
result.Add(ecBlocksArr[b][i]);
return result.ToArray();
}
}
}