示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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]);
            }
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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));
        }
示例#9
0
    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]}");
    }
示例#10
0
 public void AppendTo(ref BitList bits, byte[] text)
 => bits.AddBits(_value, _bitCount);
示例#11
0
        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);
        }
示例#12
0
		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;
		}