internal void Encode(IEncodeCallback callback, bool utf8encode = false) { if (Data is byte[]) { if (!SupportsBinary) { EncodeBase64Packet(callback); return; } EncodeByteArray(callback); return; } var encodedStringBuilder = new StringBuilder(); encodedStringBuilder.Append(_packets[Type]); if (Data != null) { encodedStringBuilder.Append(utf8encode ? UTF8.Encode((string)Data) : (string)Data); } callback.Call(encodedStringBuilder.ToString()); }
public virtual void Write(string value) { if (disposed) { throw new ObjectDisposedException("BinaryWriter", "Cannot write to a closed BinaryWriter"); } var v = value.ToCharArray(); int len = UTF8.GetByteCount(v); Write7BitEncodedInt(len); if (stringBuffer == null) { stringBuffer = new byte[512]; maxCharsPerRound = 128; } int chpos = 0; int chrem = value.Length; while (chrem > 0) { int cch = (chrem > maxCharsPerRound) ? maxCharsPerRound : chrem; int blen = UTF8.Encode(v, chpos, cch, stringBuffer, 0); OutStream.Write(stringBuffer, 0, blen); chpos += cch; chrem -= cch; } }
public virtual void Write(char ch) { if (disposed) { throw new ObjectDisposedException("BinaryWriter", "Cannot write to a closed BinaryWriter"); } char[] dec = new char[1]; dec[0] = ch; byte[] enc = UTF8.Encode(dec, 0, 1); OutStream.Write(enc, 0, enc.Length); }
public virtual void Write(char[] chars, int index, int count) { if (disposed) { throw new ObjectDisposedException("BinaryWriter", "Cannot write to a closed BinaryWriter"); } if (chars == null) { throw new ArgumentNullException("chars"); } byte[] enc = UTF8.Encode(chars, index, count); OutStream.Write(enc, 0, enc.Length); }
public static string Encode(string str, bool utf8encode) { int o1, o2, o3, bits, h1, h2, h3, h4; string[] e; string pad = ""; int c; string plain; string coded; string b64 = code; plain = utf8encode ? UTF8.Encode(str) : str; c = plain.Length % 3; // pad string to length of multiple of 3 if (c > 0) { while (c++ < 3) { pad += '='; plain += '\0'; } } // note: doing padding here saves us doing special-case packing for trailing 1 or 2 chars // e 초기화 e = new string[plain.Length / 3]; for (c = 0; c < plain.Length; c += 3) { // pack three octets into four hexets o1 = (int)plain[c]; o2 = (int)plain[c + 1]; o3 = (int)plain[c + 2]; bits = o1 << 16 | o2 << 8 | o3; h1 = bits >> 18 & 0x3f; h2 = bits >> 12 & 0x3f; h3 = bits >> 6 & 0x3f; h4 = bits & 0x3f; // use hextets to index into code string e[c / 3] = b64.Substring(h1, 1) + b64.Substring(h2, 1) + b64.Substring(h3, 1) + b64.Substring(h4, 1); } coded = string.Join("", e); // join() is far faster than repeated string concatenation in IE // replace 'A's from padded nulls with '='s coded = coded.Substring(0, coded.Length - pad.Length) + pad;//e.Slice(0, coded.Length - pad.Length) + pad; //coded.slice(0, coded.length - pad.length) + pad; return(coded); }
internal void Encode(IEncodeCallback callback, bool utf8encode = false) { if (this.Data is byte[]) { if (!this.SupportsBinary) { this.EncodeBase64Packet(callback); } else { this.EncodeByteArray(callback); } } else { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(Packet._packets[this.Type]); if (this.Data != null) { stringBuilder.Append(utf8encode ? UTF8.Encode((string)this.Data) : (string)this.Data); } callback.Call((object)stringBuilder.ToString()); } }
private void EncodingTest() { var value = UTF8.Encode(Decoded); Assert.Equal(Encoded, value); }
static public string Encrypt(string plaintext, string password, int nBits) { UInt64 blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES if (!(nBits == 128 || nBits == 192 || nBits == 256)) { return(""); // standard allows 128/192/256 bit keys } plaintext = UTF8.Encode(plaintext); password = UTF8.Encode(password); // use AES itself to encrypt password to get cipher key (using plain password as source for key // expansion) - gives us well encrypted key var nBytes = nBits / 8; // no bytes in key UInt64[] pwBytes = new UInt64[nBytes]; for (var i = 0; i < nBytes; i++) { pwBytes[i] = double.IsNaN((int)password[i]) ? 0 : (UInt64)password[i]; } UInt64[] key = cipher(pwBytes, keyExpansion(pwBytes)); // gives us 16-byte key key = key.Concat(Slice(key, 0, nBytes - 16)).ToArray <UInt64>(); // expand key to 16/24/32 bytes long // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes, // block counter in 2nd 8 bytes UInt64[] counterBlock = new UInt64[blockSize]; Int64 nonce = GetUTCTime(); // timestamp: milliseconds since 1-Jan-1970 UInt64 nonceSec = (UInt64)Math.Floor((double)(nonce / 1000)); UInt64 nonceMs = (UInt64)(nonce % 1000); // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes for (var i = 0; i < 4; i++) { counterBlock[i] = (nonceSec >> i * 8) & 0xff; } for (var i = 0; i < 4; i++) { counterBlock[i + 4] = nonceMs & 0xff; } // and convert it to a string to go on the front of the ciphertext var ctrTxt = ""; for (var i = 0; i < 8; i++) { ctrTxt += ((char)counterBlock[i]).ToString(); //String.fromCharCode(counterBlock[i]); } // generate key schedule - an expansion of the key into distinct Key Rounds for each round var keySchedule = keyExpansion(key); UInt64 blockCount = (UInt64)Math.Ceiling((decimal)plaintext.Length / (decimal)blockSize); string[] ciphertxt = new string[blockCount]; // ciphertext as array of strings for (UInt64 b = 0; b < blockCount; b++) { // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB) for (int c = 0; c < 4; c++) { counterBlock[15 - c] = (b >> c * 8) & 0xff; } for (int c = 0; c < 4; c++) { counterBlock[15 - c - 4] = (b / (UInt64)0x100000000 >> c * 8); } UInt64[] cipherCntr = cipher(counterBlock, keySchedule); // -- encrypt counter block -- // block size is reduced on final block UInt64 blockLength = b < blockCount - 1 ? blockSize : ((UInt64)plaintext.Length - 1) % blockSize + 1; String[] cipherChar = new String[blockLength]; for (int i = 0; i < (int)blockLength; i++) { // -- xor plaintext with ciphered counter char-by-char -- cipherChar[i] = ((char)((int)cipherCntr[i] ^ (int)plaintext[(int)b * (int)blockSize + i])).ToString(); } ciphertxt[b] = string.Join("", cipherChar); } // Array.join is more efficient than repeated string concatenation in IE string ciphertext = ctrTxt + string.Join("", ciphertxt); // Base64 Encode ciphertext = Base64.Endode(ciphertext); return(ciphertext); }
static public string Decrypt(string ciphertext, string password, int nBits) { int blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES if (!(nBits == 128 || nBits == 192 || nBits == 256)) { return(""); // standard allows 128/192/256 bit keys } ciphertext = Base64.Decode(ciphertext); password = UTF8.Encode(password); // use AES to encrypt password (mirroring encrypt routine) var nBytes = nBits / 8; // no bytes in key UInt64[] pwBytes = new UInt64[nBytes]; for (var i = 0; i < nBytes; i++) { pwBytes[i] = double.IsNaN((int)password[i]) ? 0 : (UInt64)password[i]; } UInt64[] key = cipher(pwBytes, keyExpansion(pwBytes)); key = key.Concat(Slice(key, 0, nBytes - 16)).ToArray <UInt64>(); // expand key to 16/24/32 bytes long // recover nonce from 1st 8 bytes of ciphertext UInt64[] counterBlock = new UInt64[blockSize]; string ctrTxt = ciphertext.Substring(0, 8); for (var i = 0; i < 8; i++) { counterBlock[i] = (UInt64)ctrTxt[i]; } // generate key schedule var keySchedule = keyExpansion(key); // separate ciphertext into blocks (skipping past initial 8 bytes) int nBlocks = (int)Math.Ceiling((decimal)(ciphertext.Length - 8) / (decimal)blockSize); string[] ct = new string[nBlocks]; for (var b = 0; b < nBlocks; b++) { ct[b] = Slice(ciphertext, 8 + b * blockSize, 8 + b * blockSize + blockSize <= ciphertext.Length ? 8 + b * blockSize + blockSize : ciphertext.Length); } // plaintext will get generated block-by-block into array of block-length strings string[] plaintxt = new string[ct.Length]; for (var b = 0; b < nBlocks; b++) { // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) for (var c = 0; c < 4; c++) { counterBlock[15 - c] = (UInt64)((b) >> c * 8) & 0xff; } for (var c = 0; c < 4; c++) { counterBlock[15 - c - 4] = (UInt64)(((int)((b + 1) / (decimal)(((UInt64)0x100000000)) - 1)) >> c * 8) & 0xff; } var cipherCntr = cipher(counterBlock, keySchedule); // encrypt counter block UInt64[] plaintxtByte = new UInt64[ct[b].Length]; string[] plaintxtString = new string[ct[b].Length]; for (var i = 0; i < ct[b].Length; i++) { // -- xor plaintxt with ciphered counter byte-by-byte -- plaintxtByte[i] = cipherCntr[i] ^ (UInt64)ct[b][i]; plaintxtString[i] = ((char)plaintxtByte[i]).ToString(); } plaintxt[b] = string.Join("", plaintxtString); } // join array of blocks into single plaintext string var plaintext = string.Join("", plaintxt); plaintext = UTF8.Decode(plaintext); // decode from UTF8 back to Unicode multi-byte chars return(plaintext); }