Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (9.26 MB, 1,017 trang )
CHAPTER 2 ■ DATA MANIPULATION
Solution
Use the static methods ToBase64CharArray and FromBase64CharArray of the System.Convert class to
convert your binary data to and from a Base64-encoded char array. If you need to work with the encoded
data as a string value instead of a char array, you can use the ToBase64String and FromBase64String
methods of the Convert class instead.
How It Works
Base64 is an encoding scheme that enables you to represent binary data as a series of ASCII characters
so that it can be included in text files and e-mail messages in which raw binary data is unacceptable.
Base64 encoding works by spreading the contents of 3 bytes of input data across 4 bytes and ensuring
each byte uses only the 7 low-order bits to contain data. This means that each byte of Base64-encoded
data is equivalent to an ASCII character and can be stored or transmitted anywhere ASCII characters are
permitted.
The ToBase64CharArray and FromBase64CharArray methods of the Convert class make it
straightforward to Base64 encode and decode data. However, before Base64 encoding, you must convert
your data to a byte array. Similarly, when decoding you must convert the byte array back to the
appropriate data type. See recipe 2-2 for details on converting string data to and from byte arrays and
recipe 2-3 for details on converting basic value types. The ToBase64String and FromBase64String
methods of the Convert class deal with string representations of Base64-encoded data.
The Code
The example shown here demonstrates how to Base64 encode and decode a byte array, a Unicode string,
an int type, and a decimal type using the Convert class. The DecimalToBase64 and Base64ToDecimal
methods rely on the ByteArrayToDecimal and DecimalToByteArray methods listed in recipe 2-3.
using System;
using System.IO;
using System.Text;
namespace Apress.VisualCSharpRecipes.Chapter02
{
class Recipe02_04
{
// Create a byte array from a decimal.
public static byte[] DecimalToByteArray (decimal src)
{
// Create a MemoryStream as a buffer to hold the binary data.
using (MemoryStream stream = new MemoryStream())
{
// Create a BinaryWriter to write binary data the stream.
using (BinaryWriter writer = new BinaryWriter(stream))
{
// Write the decimal to the BinaryWriter/MemoryStream.
writer.Write(src);
62
CHAPTER 2 ■ DATA MANIPULATION
// Return the byte representation of the decimal.
return stream.ToArray();
}
}
}
// Create a decimal from a byte array.
public static decimal ByteArrayToDecimal (byte[] src)
{
// Create a MemoryStream containing the byte array.
using (MemoryStream stream = new MemoryStream(src))
{
// Create a BinaryReader to read the decimal from the stream.
using (BinaryReader reader = new BinaryReader(stream))
{
// Read and return the decimal from the
// BinaryReader/MemoryStream.
return reader.ReadDecimal();
}
}
}
// Base64 encode a Unicode string.
public static string StringToBase64 (string src)
{
// Get a byte representation of the source string.
byte[] b = Encoding.Unicode.GetBytes(src);
// Return the Base64-encoded string.
return Convert.ToBase64String(b);
}
// Decode a Base64-encoded Unicode string.
public static string Base64ToString (string src)
{
// Decode the Base64-encoded string to a byte array.
byte[] b = Convert.FromBase64String(src);
// Return the decoded Unicode string.
return Encoding.Unicode.GetString(b);
}
// Base64 encode a decimal.
public static string DecimalToBase64 (decimal src)
{
// Get a byte representation of the decimal.
byte[] b = DecimalToByteArray(src);
// Return the Base64-encoded decimal.
return Convert.ToBase64String(b);
}
63
CHAPTER 2 ■ DATA MANIPULATION
// Decode a Base64-encoded decimal.
public static decimal Base64ToDecimal (string src)
{
// Decode the Base64-encoded decimal to a byte array.
byte[] b = Convert.FromBase64String(src);
// Return the decoded decimal.
return ByteArrayToDecimal(b);
}
// Base64 encode an int.
public static string IntToBase64 (int src)
{
// Get a byte representation of the int.
byte[] b = BitConverter.GetBytes(src);
// Return the Base64-encoded int.
return Convert.ToBase64String(b);
}
// Decode a Base64-encoded int.
public static int Base64ToInt (string src)
{
// Decode the Base64-encoded int to a byte array.
byte[] b = Convert.FromBase64String(src);
// Return the decoded int.
return BitConverter.ToInt32(b,0);
}
public static void Main()
{
// Encode and decode a general byte array. Need to create a char[]
// to hold the Base64-encoded data. The size of the char[] must
// be at least 4/3 the size of the source byte[] and must be
// divisible by 4.
byte[] data = { 0x04, 0x43, 0x5F, 0xFF, 0x0, 0xF0, 0x2D, 0x62, 0x78,
0x22, 0x15, 0x51, 0x5A, 0xD6, 0x0C, 0x59, 0x36, 0x63, 0xBD, 0xC2,
0xD5, 0x0F, 0x8C, 0xF5, 0xCA, 0x0C};
64
CHAPTER 2 ■ DATA MANIPULATION
char[] base64data =
new char[(int)(Math.Ceiling((double)data.Length / 3) * 4)];
Console.WriteLine("\nByte array encoding/decoding");
Convert.ToBase64CharArray(data, 0, data.Length, base64data, 0);
Console.WriteLine(new String(base64data));
Console.WriteLine(BitConverter.ToString(
Convert.FromBase64CharArray(base64data, 0, base64data.Length)));
// Encode and decode a string.
Console.WriteLine(StringToBase64
("Welcome to Visual C# Recipes from Apress"));
Console.WriteLine(Base64ToString("VwBlAGwAYwBvAG0AZQAgAHQAbwA" +
"gAFYAaQBzAHUAYQBsACAAQwAjACAAUgBlAGMAaQBwAGUAcwAgAGYAcgB" +
"vAG0AIABBAHAAcgBlAHMAcwA="));
// Encode and decode a decimal.
Console.WriteLine(DecimalToBase64(285998345545.563846696m));
Console.WriteLine(Base64ToDecimal("KDjBUP07BoEPAAAAAAAJAA=="));
// Encode and decode an int.
Console.WriteLine(IntToBase64(35789));
Console.WriteLine(Base64ToInt("zYsAAA=="));
// Wait to continue.
Console.WriteLine("\nMain method complete. Press Enter");
Console.ReadLine();
}
}
}
■ Caution If you Base64 encode binary data for the purpose of including it as MIME data in an e-mail message,
be aware that the maximum allowed line length in MIME for Base64-encoded data is 76 characters. Therefore, if
your data is longer than 76 characters, you must insert a new line. For further information about the MIME
standard, consult RFCs 2045 through 2049, which can be found at www.ietf.org/rfc.html.
2-5. Validate Input Using Regular Expressions
Problem
You need to validate that user input or data read from a file has the expected structure and content. For
example, you want to ensure that a user enters a valid IP address, telephone number, or e-mail address.
65
CHAPTER 2 ■ DATA MANIPULATION
Solution
Use regular expressions to ensure that the input data follows the correct structure and contains only
valid characters for the expected type of information.
How It Works
When a user inputs data to your application or your application reads data from a file, it’s good practice
to assume that the data is bad until you have verified its accuracy. One common validation requirement
is to ensure that data entries such as e-mail addresses, telephone numbers, and credit card numbers
follow the pattern and content constraints expected of such data. Obviously, you cannot be sure the
actual data entered is valid until you use it, and you cannot compare it against values that are known to
be correct. However, ensuring the data has the correct structure and content is a good first step to
determining whether the input is accurate. Regular expressions provide an excellent mechanism for
evaluating strings for the presence of patterns, and you can use this to your advantage when validating
input data.
The first thing you must do is figure out the regular expression syntax that will correctly match the
structure and content of the data you are trying to validate. This is by far the most difficult aspect of
using regular expressions. Many resources exist to help you with regular expressions, such as The
Regulator (http://osherove.com/tools), and RegExDesigner.NET, by Chris Sells
(www.sellsbrothers.com/tools/#regexd). The RegExLib.com web site (www.regxlib.com) also provides
hundreds of useful prebuilt expressions.
Regular expressions are constructed from two types of elements: literals and metacharacters.
Literals represent specific characters that appear in the pattern you want to match. Metacharacters
provide support for wildcard matching, ranges, grouping, repetition, conditionals, and other control
mechanisms. Table 2-2 describes some of the more commonly used regular expression metacharacter
elements. (Consult the .NET SDK documentation for a full description of regular expressions. A good
starting point is http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.
regex.aspx.)
Table 2-2. Commonly Used Regular Expression Metacharacter Elements
Element
.
Specifies any character except a newline character (\n)
\d
Specifies any decimal digit
\D
Specifies any nondigit
\s
Specifies any whitespace character
\S
Specifies any non-whitespace character
\w
Specifies any word character
\W
66
Description
Specifies any nonword character