Tom's post a few days ago about turning strings into numbers made me wonder
if the ASCII-to-number of a person's name is a prime number. This Friday
evening I coded the console command below that asks for string names and
tests if the resulting BigInteger class made from the ASCII bytes is
probably prime. Some random sampling code (not shown) hints that the chance
of a string composed from the typical frequency distribution of the English
alphabet has about a 2% chance of being prime. So if your name is prime then
you are 1 in 50 special.

 

But seriously, the System.Numerics namespace in Framework 4.0 was a surprise
arrival, but it's a shame it's so small with containing two classes. A
"BigDecimal" class would have been an impressive addition.

 

Greg

 

using System;

using System.Text;

using System.Linq;

using System.Numerics;

 

namespace bigintplay

{

  /// <summary>

  /// A bit of nonsense that takes a string (expected to be a person's
name), gets the

  /// ASCII bytes, reverses the byte into little endian order, constructs a
BigInteger

  /// from the reversed bytes and then checks if the result it a probable
prime number.

  /// Primality testing is done by trial division of small primes and also
by the Fermat

  /// probablistic test (look it up to see why it's probabilistic due to
those damned

  /// Carmichael numbers).

  /// </summary>

  public sealed class Program

  {

    const int FermatCount = 10;

    static int[] smallPrimes =

    {

 
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,1
03,107,109,113,

 
127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,
229,233,239,241,251,257,263,269,271,277,281,

 
283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,
409,419,421,431,433,439,443,449,457,461,463,

 
467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,
601,607,613,617,619,631,641,643,647,653,659,

 
661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,
809,811,821,823,827,829,839,853,857,859,863,

 
877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997

    };

 

    static void Main(string[] args)

    {

      NameChecker();

    }

 

    private static void NameChecker()

    {

      while (true)

      {

        Console.ResetColor();

        Console.Write("Enter a name to test: ");

        string name = Console.ReadLine();

        if (name.Length == 0)

        {

          break;

        }

        Info("------------------------------------------------");

        Info("Processing name\n\u25ba {0}", name);

        byte[] rawbuff = Encoding.ASCII.GetBytes(name);

        Info("Raw ASCII bytes\n\u25ba {0}", Hex(rawbuff));

        byte[] littlebuff = rawbuff.Reverse().ToArray();

        Info("Little endian\n\u25ba {0}", Hex(littlebuff));

        BigInteger bi = new BigInteger(littlebuff);

        Info("Number from little endian\n\u25ba {0}", bi);

        bool failed = false;

        var divs = (from s in smallPrimes where s < bi &&
BigInteger.Remainder(bi, s).IsZero select s);

        if (divs.Any())

        {

          Console.ForegroundColor = ConsoleColor.Yellow;

          Info("Trivial factors: {0}", string.Join(" ", (from div in divs
select div.ToString()).ToArray()));

          failed = true;

        }

        for (int i = 0; i < FermatCount; i++)

        {

          int small = smallPrimes[i];

          if (small < (bi - 1))

          {

            BigInteger mod = BigInteger.ModPow(small, bi - 1, bi);

            if (!mod.IsOne)

            {

              Console.ForegroundColor = ConsoleColor.Yellow;

              Info("Failed Fermat primality test for modulus {0}", small);

              Console.ResetColor();

              failed = true;

              break;

            }

          }

        }

        if (failed)

        {

          Console.ForegroundColor = ConsoleColor.Red;

          Info("YOUR NAME IS NOT PRIME");

        }

        else

        {

          Console.ForegroundColor = ConsoleColor.Cyan;

         Info("Congratulations! Your name is probably prime");

          Info("(the chance of this seems to be about 1 in 50)");

        }

      }

    }

 

    private static string Hex(byte[] buff)

    {

      return BitConverter.ToString(buff).Replace("-", "");

    }

 

    private static void Info(string format, params object[] args)

    {

      Console.WriteLine(format, args);

    }

  }

}

 

 

Reply via email to