private static BitList StuffBits(BitList bits, int wordSize) { var result = new BitList(); int n = bits.Length; uint mask = (uint)((1 << wordSize) - 2); for (int i = 0; i < n; i += wordSize) { uint word = 0; for (int j = 0; j < wordSize; j++) { if (i + j >= n || bits.GetBit(i + j)) { word |= (uint)(1 << (wordSize - 1 - j)); } } if ((word & mask) == mask) { result.AddBits(word & mask, (byte)wordSize); i--; } else if ((word & mask) == 0) { result.AddBits(word | 1, (byte)wordSize); i--; } else { result.AddBits(word, (byte)wordSize); } } return(result); }
public override (BitList, VersionInfo) Encode(string content, ErrorCorrectionLevel errorCorrectionLevel) { if (content == null) { throw new ArgumentNullException(nameof(content)); } byte[] data = TextEncoding.UTF8.GetBytes(content); EncodingMode encodingMode = EncodingMode.Byte; var versionInfo = VersionInfo.FindSmallestVersionInfo(errorCorrectionLevel, encodingMode, data.Length * 8); if (versionInfo == null) { throw new InvalidOperationException("Too much data to encode"); } var bits = new BitList(); bits.AddBits((uint)encodingMode, 4); bits.AddBits((uint)content.Length, versionInfo.CharCountBits(encodingMode)); foreach (var b in data) { bits.AddByte(b); } AddPaddingAndTerminator(ref bits, versionInfo); return(bits, versionInfo); }
public void AppendTo(ref BitList bits, byte[] text) { for (var i = 0; i < _shiftByteCount; i++) { if (i == 0 || (i == 31 && _shiftByteCount <= 62)) { // We need a header before the first character, and before // character 31 when the total byte code is <= 62 bits.AddBits(31, 5); // BINARY_SHIFT if (_shiftByteCount > 62) { bits.AddBits((uint)_shiftByteCount - 31, 16); } else if (i == 0) { // 1 <= binaryShiftByteCode <= 62 if (_shiftByteCount < 31) { bits.AddBits((uint)_shiftByteCount, 5); } else { bits.AddBits(31, 5); } } else { // 32 <= binaryShiftCount <= 62 and i == 31 bits.AddBits((uint)_shiftByteCount - 31, 5); } } bits.AddByte(text[_shiftStart + i]); } }
public static BitList GenerateCheckWords(BitList bits, int totalBits, int wordSize) { var rs = new ReedSolomonEncoder(GetGaloisField(wordSize)); // bits is guaranteed to be a multiple of the wordSize, so no padding needed int messageWordCount = bits.Length / wordSize; int totalWordCount = totalBits / wordSize; int eccWordCount = totalWordCount - messageWordCount; int[] messageWords = BitsToWords(bits, wordSize, messageWordCount); int[] eccWords = rs.Encode(messageWords, eccWordCount); int startPad = totalBits % wordSize; var messageBits = new BitList(); messageBits.AddBits(0, (byte)startPad); foreach (var messageWord in messageWords) { messageBits.AddBits((uint)messageWord, (byte)wordSize); } foreach (var eccWord in eccWords) { messageBits.AddBits((uint)eccWord, (byte)wordSize); } return(messageBits); }
public override (BitList, VersionInfo) Encode(string content, ErrorCorrectionLevel errorCorrectionLevel) { if (content == null) { throw new ArgumentNullException(nameof(content)); } bool contentLengthIsOdd = content.Length % 2 == 1; int contentBitCount = (content.Length / 2) * 11; if (contentLengthIsOdd) { contentBitCount += 6; } EncodingMode encodingMode = EncodingMode.AlphaNumeric; var versionInfo = VersionInfo.FindSmallestVersionInfo(errorCorrectionLevel, encodingMode, contentBitCount); if (versionInfo == null) { throw new InvalidOperationException("Too much data to encode"); } var bits = new BitList(); bits.AddBits((uint)encodingMode, 4); bits.AddBits((uint)content.Length, versionInfo.CharCountBits(encodingMode)); var encoder = new Queue <int>(content.Select(x => CharSet.IndexOf(x))); for (int i = 0; i < content.Length / 2; i++) { int c1 = encoder.Dequeue(); int c2 = encoder.Dequeue(); if (c1 < 0 || c2 < 0) { throw new InvalidOperationException($"{content} can not be ancoded as {encodingMode}"); } bits.AddBits((uint)(c1 * 45 + c2), 11); } if (contentLengthIsOdd) { int c = encoder.Dequeue(); if (c < 0) { throw new InvalidOperationException($"{content} can not be ancoded as {encodingMode}"); } bits.AddBits((uint)c, 6); } AddPaddingAndTerminator(ref bits, versionInfo); return(bits, versionInfo); }
private static BitList GenerateModeMessage(bool compact, int layers, int messageSizeInWords) { var modeMessage = new BitList(); if (compact) { modeMessage.AddBits((uint)layers - 1, 2); modeMessage.AddBits((uint)messageSizeInWords - 1, 6); modeMessage = ErrorCorrection.GenerateCheckWords(modeMessage, 28, 4); } else { modeMessage.AddBits((uint)layers - 1, 5); modeMessage.AddBits((uint)messageSizeInWords - 1, 11); modeMessage = ErrorCorrection.GenerateCheckWords(modeMessage, 40, 4); } return(modeMessage); }
private static BitList RenderBarcode(IEnumerable <int[]> codes) { var bl = new BitList(); foreach (int[] row in codes) { var lastIdx = row.Length - 1; for (int i = 0; i < row.Length; i++) { int col = row[i]; if (i == lastIdx) { bl.AddBits((uint)col, 18); } else { bl.AddBits((uint)col, 17); } } } return(bl); }
public static IBarcode Encode(string content, bool includeChecksum, bool fullAsciiMode) { if (content == null) { throw new ArgumentNullException(nameof(content)); } if (fullAsciiMode) { content = Prepare(content); } else if (content.Contains("*")) { throw new InvalidOperationException("Invalid data! Try full ASCII mode"); } var data = content; if (includeChecksum) { data += GetChecksum(content, 20); data += GetChecksum(data, 15); } data = "*" + data + "*"; var result = new BitList(); foreach (var r in data) { if (!Code93Constants.EncodingTable.TryGetValue(r, out (int value, uint data)info)) { throw new InvalidOperationException("Invalid data"); } result.AddBits(info.data, 9); } result.AddBit(true); return(new Base1DCode(result, BarcodeType.Code93, content, Code93Constants.Margin)); }
public string Encrypt(string message) { var bitList = new BitList(new BitArray(Encoding.UTF8.GetBytes(message))); if (bitList.Count > 256) { throw new SHA_256_Exception("Message must be equal or less then 256 bit"); } bitList.ListOfBits.Add(true); //Added one bit if (bitList.Count < 448) //Added (L + 1 + K) mod 512 zero bits { bitList.AddBits(448 - bitList.Count); } BitList.Concate(bitList.ListOfBits, new BitList(new BitArray(message.Length), 64).ListOfBits); //Added 64 bit word length var blocks32 = BitList.Split(bitList, 32); for (int i = 16; i < 63; i++) { var s0 = (BitList.RotRight(blocks32[i - 15].ListOfBits, 7)) ^ (BitList.RotRight(blocks32[i - 15].ListOfBits, 18)) ^ (BitList.LogicRight(blocks32[i - 15], 3)); var s1 = (BitList.RotRight(blocks32[i - 2].ListOfBits, 17)) ^ (BitList.RotRight(blocks32[i - 2].ListOfBits, 19)) ^ (BitList.LogicRight(blocks32[i - 2], 10)); blocks32.Add((blocks32[i - 16] + s0) + (blocks32[i - 7] + s1)); } var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; var f = H[5]; var g = H[6]; var h = H[7]; for (int i = 0; i < 63; i++) { var sum0 = (a >> 2) ^ (a >> 13) ^ (a >> 22); var Ma = (a & b) ^ (a & c) ^ (b & c); var t2 = sum0 + Ma; var sum1 = (e >> 6) ^ (e >> 11) ^ (e >> 25); var Ch = (e & f) ^ ((~e) & g); var t1 = h + sum1 + Ch + blocks32[i] + K[i]; h = g; g = f; f = e; e = t1 + d; d = c; c = b; b = a; a = t1 + t2; } H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; return($"{H[0]} {H[1]} {H[2]} {H[3]} {H[4]} {H[5]} {H[6]} {H[7]}"); }
public void AppendTo(ref BitList bits, byte[] text) => bits.AddBits(_value, _bitCount);
public override (BitList, VersionInfo) Encode(string content, ErrorCorrectionLevel errorCorrectionLevel) { if (content == null) { throw new ArgumentNullException(nameof(content)); } var contentBitCount = (content.Length / 3) * 10; switch (content.Length % 3) { case 1: contentBitCount += 4; break; case 2: contentBitCount += 7; break; } EncodingMode encodingMode = EncodingMode.Numeric; var versionInfo = VersionInfo.FindSmallestVersionInfo(errorCorrectionLevel, encodingMode, contentBitCount); if (versionInfo == null) { throw new InvalidOperationException("Too much data to encode"); } var bits = new BitList(); bits.AddBits((uint)encodingMode, 4); bits.AddBits((uint)content.Length, versionInfo.CharCountBits(encodingMode)); for (int i = 0; i < content.Length; i += 3) { string currentContentPart = i + 3 <= content.Length ? content.Substring(i, 3) : content.Substring(i); if (!uint.TryParse(currentContentPart, out uint currentNumericalValue)) { throw new InvalidOperationException($"{content} can not be ancoded as {encodingMode}"); } byte bitCount; switch (currentContentPart.Length % 3) { case 0: bitCount = 10; break; case 1: bitCount = 4; break; case 2: bitCount = 7; break; default: throw new InvalidOperationException(); } bits.AddBits(currentNumericalValue, bitCount); } AddPaddingAndTerminator(ref bits, versionInfo); return(bits, versionInfo); }
private static CodeMatrix GetEncodedMatrix(byte[] data, bool stringData){ if(data==null)throw new ArgumentNullException("data"); if(data.Length>7089)throw new ArgumentException("'data' length is too long."); bool allnumeric=stringData; bool alphanumeric=stringData; int version=-1; if(stringData){ for(int i=0;i<data.Length;i++){ byte d=data[i]; if(d<0x30 || d>=0x3a){ allnumeric=false; } if(d<0x20 || d>=0x60 || CharToValue[d-0x20]==0){ alphanumeric=false; } } } //Console.WriteLine("{0} {1}",alphanumeric,stringData); if(allnumeric){ for(int i=0;i<versionsnumeric.Length;i++){ if(data.Length<=versionsnumeric[i]){ version=i; break; } } } else if(alphanumeric){ for(int i=0;i<versionsalphanum.Length;i++){ if(data.Length<=versionsalphanum[i]){ version=i; break; } } } else { for(int i=0;i<versions.Length;i++){ if(data.Length<=versions[i]){ version=i; break; } } } if(version<0){ throw new ArgumentException("'data' length is too long."); } BitList bl=new BitList(); if(allnumeric){ bl.AddBits((byte)1,4); int datacount=10; if(version>=9 && version<=25)datacount=12; if(version>=26)datacount=14; bl.AddBits(data.Length,datacount); int runningcount=0; int runningdigits=0; for(int i=0;i<data.Length;i++){ runningdigits*=10; runningdigits+=((int)data[i]-0x30); runningcount++; if(runningcount==3){ bl.AddBits(runningdigits,10); runningcount=0; runningdigits=0; } } if(runningcount>0){ bl.AddBits(runningdigits,(runningcount==1) ? 4 : 7); } } else if(alphanumeric){ bl.AddBits((byte)2,4); int datacount=9; if(version>=9 && version<=25)datacount=11; if(version>=26)datacount=13; bl.AddBits(data.Length,datacount); //Console.WriteLine("{0} ver={1}",data.Length,version+1); int runningcount=0; int runningdigits=0; for(int i=0;i<data.Length;i++){ runningdigits*=45; runningdigits+=CharToValue[data[i]-0x20]; runningcount++; if(runningcount==2){ bl.AddBits(runningdigits,11); runningcount=0; runningdigits=0; } } if(runningcount>0){ bl.AddBits(runningdigits,6); } } else { bl.AddBits((byte)4,4); bl.AddBits(data.Length,(version<9) ? 8 : 16); for(int i=0;i<data.Length;i++){ bl.AddBits(data[i],8); } } int matrixSize=21+version*4; int dataWords=(version<9) ? versions[version]+2 : versions[version]+3; bl.PadTo(dataWords); //Console.WriteLine(ArrayUtil.ArrayToString(bl.List)); int rsOffset=version*6; int dataOffset=0; int ecOffset=0; int firstBlockCount=DataBlocks[rsOffset]; int secondBlockCount=DataBlocks[rsOffset+3]; int totalBlockCount=firstBlockCount+secondBlockCount; // first all data blocks then all error correction blocks int[] codewordOffsets=new int[totalBlockCount*2]; for(int i=0;i<firstBlockCount;i++){ ReedSolomonEncode(bl.List,dataOffset, DataBlocks[rsOffset+1], DataBlocks[rsOffset+2]); codewordOffsets[i]=dataOffset; codewordOffsets[totalBlockCount+i]=dataWords+ecOffset; dataOffset+=DataBlocks[rsOffset+1]; ecOffset+=DataBlocks[rsOffset+2]; } for(int i=0;i<secondBlockCount;i++){ ReedSolomonEncode(bl.List,dataOffset, DataBlocks[rsOffset+4], DataBlocks[rsOffset+5]); codewordOffsets[i+DataBlocks[rsOffset]]=dataOffset; codewordOffsets[i+totalBlockCount+DataBlocks[rsOffset]]=dataWords+ecOffset; dataOffset+=DataBlocks[rsOffset+4]; } //Console.WriteLine(ArrayUtil.ArrayToString(bl.List)); CodeMatrix matrix=new CodeMatrix(matrixSize); matrix.DrawFinderPattern(0,0); matrix.DrawFinderPattern(0,matrixSize-7); matrix.DrawFinderPattern(matrixSize-7,0); matrix.DrawTimingPatterns(); matrix.SetFormatInfo(0); if(version>=6){ matrix.SetVersionInfo(0); } int alignOffset=version*7; for(int y=0;y<7;y++){ for(int x=0;x<7;x++){ matrix.DrawAlignmentPattern(AlignmentPatterns[alignOffset+x], AlignmentPatterns[alignOffset+y]); } } // Set data words int minSizePerBlock=DataBlocks[rsOffset+1]; for(int i=0;i<minSizePerBlock;i++){ for(int j=0;j<totalBlockCount;j++){ //Console.WriteLine("{0}->{0:X2}",codewordOffsets[j],bl.List[codewordOffsets[j]]); int index=codewordOffsets[j]; matrix.SetNextCodeword(bl.List[index]); codewordOffsets[j]++; } } if(secondBlockCount!=0){ for(int j=0;j<secondBlockCount;j++){ int index=codewordOffsets[j+firstBlockCount]; matrix.SetNextCodeword(bl.List[index]); codewordOffsets[j+firstBlockCount]++; } } // Set error correction words minSizePerBlock=DataBlocks[rsOffset+2]; for(int i=0;i<minSizePerBlock;i++){ for(int j=0;j<totalBlockCount;j++){ int index=codewordOffsets[j+totalBlockCount]; matrix.SetNextCodeword(bl.List[index]); codewordOffsets[j+totalBlockCount]++; } } // Mask the data int lowestPenalty=0; int bestMask=0; for(int i=0;i<8;i++){ matrix.ApplyMask(i); int penalty=matrix.CalculatePenalty(); if(i==0 || penalty<lowestPenalty){ bestMask=i; lowestPenalty=penalty; } // Reapply the mask to erase it matrix.ApplyMask(i); } matrix.ApplyMask(bestMask); matrix.SetFormatInfo(FormatInfo[bestMask]); //Console.WriteLine("format={0}",FormatInfo[bestMask]); if(version>=6){ // Console.WriteLine("version={0}",version+1); // Console.WriteLine("version={0:X5}",VersionInfo[version-6]); matrix.SetVersionInfo(VersionInfo[version-6]); } return matrix; }