#985 – Why It’s Useful for Conditional Operators to Short-Circuit Evaluation

C# won’t necessarily evaluate every sub-expression in a larger expression.  If knowing the value of the first operand is sufficient for knowing the value of the entire expression, the larger expression is said to be short-circuited.

For example, when evaluating a logical AND (&&), the second operand will not be evaluated if the first operand is false.

Short-circuiting is useful in cases when evaluating later operands would throw an exception.

For example, in the code below, if the variable d is null, the first operand is false, which means that the entire expression is evaluated as false.  d.CanBark, which would throw an exception, is not evaluated.

            // d is of type Dog
            if ((d != null) && (d.CanBark))
                d.Bark();

Without the ability to short-circuit the expression, we’d have to do the check in two different if statements:

            if (d != null)
                if (d.CanBark)
                    d.Bark();
Advertisement

#984 – The Birthday Problem

To celebrate today’s Thanksgiving holiday in the United States, the post today is just a fun little code fragment for exploring the birthday problem.  The idea of the birthday problem is to look at the probability of having at least one shared birthday in a group of n people.

Instead of calculating the actual probability of a collision, the code below empirically creates a group of people, assigns them birthdays, and then looks for shared birthdays.  It does this 100,000 times and then reports what percentage of time there actually was a match.

        static void Main(string[] args)
        {
            while (true)
            {
                Console.Write("Enter # people: ");
                int numPeople = int.Parse(Console.ReadLine());

                const double NumTrials = 100000.0;

                int numBirthdayMatches = 0;
                double numUniqueBirthdaySum = 0;

                List<int> personBirthdays;
                Random rnd = new Random();

                for (int trialNum = 1; trialNum <= NumTrials; trialNum++)
                {
                    // Generate birthdays
                    personBirthdays = new List<int>(numPeople);
                    for (int personNum = 1; personNum <= numPeople; personNum++)
                        personBirthdays.Add(rnd.Next(1, 366));

                    if (personBirthdays.Count != personBirthdays.Distinct().Count())
                        numBirthdayMatches++;

                    numUniqueBirthdaySum += personBirthdays.Distinct().Count();
                }

                double percentMatched =
                    numBirthdayMatches / NumTrials * 100.0;
                double numUniquePerTrial = numUniqueBirthdaySum / NumTrials;
                Console.WriteLine(string.Format("For {0} people, there was at least one matching birthday {1}% of the time.  Avg # unique birthdays={2}",
                    numPeople,
                    percentMatched,
                    numUniquePerTrial));
            }

            Console.ReadLine();
        }

984-001

#983 – Using a BitArray to Store a Large Collection of Boolean Values

If you need to store a set of boolean values, you can store them in array of type bool.  Each element of the array would require 8 bits, despite storing a single boolean value.

You can more efficiently store a set of boolean values in an enum type, marking the type with the Flags attribute.  This allows storing a maximum of 32 distinct boolean values.

To store a larger collection of boolean values, you can use the BitArray type.  A BitArray allows you to index into an array of boolean values, but stores the values in a more compact form than would be used by a normal array.

Below, we use an enum to index into a 50-element BitArray.

        public enum States
        {
            Alabama,
            // ...
            Wyoming
        }

            BitArray baStatesIveVisited = new BitArray(50);

            baStatesIveVisited[(int)States.Minnesota] = true;
            baStatesIveVisited[(int)States.Wisconsin] = true;
            baStatesIveVisited[(int)States.California] = true;

            States nextState = States.Alabama;
            foreach (bool b in baStatesIveVisited)
                Console.WriteLine("{0}:{1}", nextState++, b);

983-001

#982 – An Enum Type Can Store a Maximum of 32 Flags

When you store a boolean value in a bool type, each boolean value uses 1 byte, or 8 bits–the size of a bool instance.

You can be more efficient in storing boolean values by using each bit within a chunk of memory to represent a single boolean value.  You can do this quite easily by using an enum type to store a series of flags.  In the example below, a single value of type Talents can represent unique values for up to 8 different boolean values.

        [Flags]
        public enum Talents
        {
            Singing = 1,
            Dancing = 2,
            Juggling = 4,
            JokeTelling = 8,
            DoingMagic = 16,
            RollingTongue = 32,
            StiltWalking = 64,
            DoingSplits = 128
        };

You can set various bits using the bitwise OR operator.

            Talents myTalents = Talents.JokeTelling | Talents.Juggling | Talents.StiltWalking;

            // 76 = 8 + 4 + 64
            int asInt = (int)myTalents;

Note that you can store a maximum of 32 different flags in an enumerated type, because an enum type uses 4 bytes (32 bits) of storage.

#981 – Full List of C# Keywords

In C#, identifiers are names that you choose to use for things like variables, classes, interfaces, etc.

A keyword is a reserved name that has a specific meaning and that you can’t (generally) use as an identifier.

Here’s the full list of standard keywords in C#:

 abstract  add  as  ascending
 async  await  base  bool
 break  by  byte  case
 catch  char  checked  class
 const  continue  decimal  default
 delegate  descending  do  double
 dynamic  else  enum  equals
 explicit  extern  false  finally
 fixed  float  for  foreach
 from  get  global goto
group  if  implicit  in
 int  interface  internal  into
 is  join  let  lock
 long  namespace  new  null
 object  on  operator  orderby
 out  override  params  partial
 private  protected  public  readonly
 ref  remove  return  sbyte
 sealed  select  set  short
 sizeof  stackalloc  static  string
 struct  switch  this  throw
 true  try  typeof  uint
 ulong  unchecked  unsafe  ushort
 using  value  var  virtual
 void  volatile  where  while
 yield      

#980 – Getting Data Out of a SecureString

Confidential data stored in an instance of the SecureString type is stored in memory on the unmanaged heap, in an encrypted form.

If you need to work with the data in an unencrypted form, you can read the data out of the SecureString into an unmanaged string (BSTR).  Once you are finished working with the confidential string data, you should zero out the memory where it was stored.

Below is an example of using the Marshal.SecureStringToBSTR method to work with string data stored in a SecureString.

        private void DoSomethingWithSecureStringData(SecureString secStr)
        {
            // using System.Runtime.InteropServices
            IntPtr unmStr = Marshal.SecureStringToBSTR(secStr);

            try
            {
                // Do something with unmanaged confidential string here.
            }
            finally
            {
                Marshal.ZeroFreeBSTR(unmStr);
            }
        }

When you call the SecureStringToBSTR method, the SecureString object decrypts its data and copies it to a new BSTR, before re-encrypting it.

 

#979 – Store Confidential Data Only Within SecureString Instances

You can use the SecureString class to securely store confidential text-based data.

The most important guideline, for security purposes, when using the SecureString class is:

Never store confidential data in a managed object (other than an instance of a SecureString)

If you transfer data from a SecureString into some managed object (e.g. a string or a byte array), the data will be less secure, due to the security issues with storing data in managed objects.

If you must work with confidential data in memory within your application, the proper procedure is to extract and decrypt the string data, but to store it in an unmanaged data structure (e.g. a BSTR).  The data will be vulnerable while in memory within the unmanaged object, but you can then explicitly delete the data when done working with it, limiting the amount of time during which the data is vulnerable.

#978 – Use a SecureString Object to Store Confidential Text Data

There can be security issues with storing confidential data in the System.String type, given that the string exists in plaintext in memory and you can’t explicitly control the amount of time during the string is present in memory.

The SecureString class provides a more secure way of storing confidential string data in memory.  SecureString is more secure than the String data type because:

  • It stores the string data in memory in an encrypted form
  • The encrypted data is stored in unmanaged memory and therefore not visible to the garbage collector
  • It allows appending, inserting or removing characters, but re-encrypts the data after modifying it
  • It is mutable, avoiding the need to create extra copies when modifying the secure string
  • It zeros out the contents of the string when the SecureString object is disposed (or finalized)

#977 – Security Issues with Managed Strings

Confidential data stored in strings is vulnerable to attack during the time period that the string is stored in memory.

String data stored in managed strings in .NET is less secure than data stored in unmanaged strings.  Plaintext (non-encrypted) string data in managed strings has a longer period of time during which it is stored in memory.

Because managed strings exist on the garbage collected heap, you can’t explicitly destroy them.  The data will remain in memory until after the garbage collector has released the memory and it has been overwritten by some other object.

Since strings are immutable, you can’t overwrite the string data in a managed string object.  Writing new data results in a new instance being created.  The Garbage Collector may also create extra copies when it compacts memory.  The string data is less secure, due to the likelihood of there being multiple copies and its longer lifetime.

#976 – Security Issues when Storing Confidential Data in Strings

Applications often have periods of time during which they need to work with confidential string data, e.g. credit card numbers or passwords.  Whenever you store this confidential string data within memory, the data is vulnerable to being read by any other process on your machine that can read your application’s memory.

Since memory can be swapped out to disk, confidential data stored in memory can also end up being stored on disk, making the data vulnerable for a longer period of time.

No matter what language your application is written in, these vulnerabilities exist whenever you store confidential data within memory as a plaintext (non-encrypted) string.

When writing code that deals with confidential data, you’ll eventually need to work with that data in memory.  To maximize security, you want to reduce the amount of time during which the plaintext version of data is stored in memory.