Running with Code Like with scissors, only more dangerous

17Jan/120

A very fast, random text string generator in C#, Part One

Posted by Rob Paveza

This is about half of a type I designed a few years ago in response to my boss's assertion that I couldn't improve on the speed of random string generators. This is a pretty handy type to have around when you want to generate a character string of a fixed length. It so happens that 6 characters can fit a "base 36" number very well into just over 231 bits (it's just a little bit bigger than int.MaxValue and so it stores the value as a uint).

What is included below is a first step. I want to show how to refactor it for improved performance and where certain design scenarios might be better; for example, repeatedly calling the CreateNew method results in repeatedly creating new RNGCryptoServiceProviders. Although I believe this class is a bit better about seeds as it incorporates hardware-dependent data, it isn't necessarily cryptographically strong. You can add some strength by passing in a single RNG to each subsequent call, for example.

This sample also only goes one way: from number to string. Next time, we'll show the reverse operation.

Note: an important inclusion:

using System.Security.Cryptography;
    /// <summary>
    /// Represents a number that may be transitioned to a six-digit alphanumeric (base-36) representation.  This type is not CLS-compliant.
    /// </summary>
    [CLSCompliant(false)]
    public struct AlphaNumericNumber
    {
        private const uint MAX_VALUE = 2176782336; // = RADIX ^ 6
        private const int RADIX = 36; // 10 digits + 26 alphabetics
        private uint m_val;

        /// <summary>
        /// Creates a new <see>AlphaNumericNumber</see> with the specified value.
        /// </summary>
        /// <param name="value">The value with which to assign the number.</param>
        public AlphaNumericNumber(uint value)
        {
            if (value > MAX_VALUE)
                value %= MAX_VALUE;
            m_val = value;
        }

        /// <summary>
        /// Creates a new, random <see>AlphaNumericNumber</see>.
        /// </summary>
        /// <returns>A randomly-chosen <see>AlphaNumericNumber</see>.</returns>
        public static AlphaNumericNumber CreateNew()
        {
            byte[] container = new byte[4];
            using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
            {
                rng.GetNonZeroBytes(container);
            }

            return new AlphaNumericNumber(BitConverter.ToUInt32(container, 0));
        }

        /// <inheritdoc />
        public override string ToString()
        {
            char[] result = new char[6];
            uint msd = RADIX * RADIX * RADIX * RADIX * RADIX;

            uint currentDigit = msd;
            uint accumulator = m_val;
            unchecked
            {
                for (int charIndex = 0; charIndex < result.Length; charIndex++)
                {
                    uint currentDigitValue = accumulator / currentDigit;
                    accumulator -= (currentDigitValue * currentDigit);
                    if (currentDigitValue <= 9)
                    {
                        result[charIndex] = (char)('0' + currentDigitValue);
                    }
                    else
                    {
                        currentDigitValue -= 10; // adjust for 'A' equaling 10.
                        result[charIndex] = (char)('A' + currentDigitValue);
                    }

                    currentDigit /= RADIX;
                }
            }

            return new string(result);
        }

        /// <summary>
        /// Gets the value contained by this <see>AlphaNumericNumber</see>.
        /// </summary>
        public uint Value
        {
            get { return m_val; }
        }
    }
31Mar/091

My Job is Tools

Posted by Rob

For the last few months I’ve been working on a fairly large-sized web application for work.  The application is mostly Flex-based, so I’m working on back-end components, which are accessed via FluorineFx (an ActionScript-.NET connector).  The site also needs to integrate with Ektron, a somewhat perilous enterprise-level CMS, because a lot of the company’s web-facing data is already stored their and they want to reuse as much as possible.  The site is a completely new version of a much less-ambitious site designed for the same purpose, driven by a 400mb Access database.

So, as part of our deployment setup, our projects consist of:

  • 3 projects that encompass most of the site’s actual functionality.  One is for Ektron integration, one is for control development, and one is for the service implementations.
  • 1 tool that imports data from the old site.
  • 1 tool that imports localization data from Ektron.
  • 1 tool that creates Ektron Smart Forms in order to create that localization data.
  • 1 tool that encrypts member passwords (because until that’s done we can’t see the old members database).
  • 1 tool that both backs up Ektron staging data and also restores that data to a clean environment.
  • A team test project.
  • A test harness for other parts of the system.
  • Oh yeah, the web site.

I generally find myself on this approach whenever I’m working on a large system.  Importing data from SMF?  Write a tool.  Need to transform something into an XML format your site understands?  Write a tool. 

For me, the hardest part about getting tooling correct is making sure that I’m not wasting time when I’m designing one.  For instance, smart forms in Ektron are a cool idea, at least in concept.  I’ve found them somewhat difficult to use, but it’s still a cool idea for a CMS.  Our client wants to use Ektron to store localization data, but right now all I have are the dictionaries of English text in a Flex ActionScript file.  Here’s our process:

  • Grep the text out of the ActionScript dictionaries into a .CSV file.
  • Using Sebastien Lorien’s CSV reader, read each dictionary in one at a time.
  • Create a .xml file corresponding to the Ektron smart form exported file format.
  • Manually import or update each corresponding Ektron smart form.

When this eventually goes to the client (or to a new staging database for ourselves), we’ll run a tool on our database in “backup mode,” which will back up all of the smart forms, as well as the corresponding content rows, into a binary file.  Then we’ll run the tool on the new database in “restore mode,” which will update all of the content to the latest versions.

What does this allow us to do?

  • QA content on the test site and be confident that it’s going to be represented on the production site.  Because entering content into Ektron in this manner isn’t particularly easy, we don’t feel comfortable that we could do it with no errors.  By automating the process, we can be reasonably confident that we’ll eliminate typos.
  • Avoid repeated input time.  It might have cost me the same amount of time to write the backup/restore tool as it would have taken to just do it by hand.  However, I was fairly confident (and correct) that I’d have to do it more than once.  We get the added bonus of being able to deliver the tool to the client, who will also have to run it in their production environment.

I love writing tools. It makes everyone’s lives easier, and that’s never, ever bad.

Tagged as: , 1 Comment
13May/080

Awesome Code Snippet Plugin for Windows Live Writer

Posted by Rob

I've enjoyed Windows Live Writer as a blog editing tool for a while now (in fact, I think all of my blog entries have been written with it).  WLW includes a nifty SDK (one that I haven't had a chance to play with yet) that enables add-in creation.  Leo Vildosola created it, based on the more recent plugin I used in fact.

This is the third code snippet plugin I've used (just started this one today, in fact) and it's definitely the best.  It has some nice features; if you look at the previous post, you'll see that it enables code to be contained within a container element, so that long listings don't need to take up pages.  Very nice.  It also has a mini mode!  What more could you want?

I need to make a stamp graphic or something that says "Rob's Stamp of Approval". :-)

Tagged as: , , No Comments
23Jan/080

ShinyDesign – a Brighter Face for the PropertyGrid

Posted by Rob

I've officially released my property grid extension project, called "ShinyDesign," under the open-source BSD-like license.  I blogged about this project just a few days ago, and I'm excited to be releasing it to the public domain.

In truth, there are some ugly hacks, and I'm sure I could have done a better job commenting on what I did.  All told, the multiple-tab hack is probably the worst.  The Windows Forms PropertyGrid does not allow you to directly add additional property tabs; rather, you add Type objects that represent the tabs.  The good news is that there's a virtual method that allows you to create the tab given the Type.  The bad news is that the PropertyGrid will block you from creating additional tabs of the same Type.  The consequent solution is that, in the PropertyGridEx control, if additional tabs are used, I dynamically define an assembly and type for each PropertyTab being created.  The type is a cleaned-up version of the tab name, and the closed types are cached (if the same property tab name is used on the same PropertyGridEx in the future).  The types are then used to close a generic ExtensionPropertyTab<T> class, and the type parameter is then ignored from there.  Oh, the things we do!

The ShinyDesign documentation is available on the web as well as a direct download.  The code is also available from my website, and details for accessing it through Subversion are also provided.

Hopefully, people find it easy to use - simply drop the PropertyGridEx control onto your form, decorate your object with a few additional attributes, and you're set.  Using the PropertyGridEx is just about as painless as a run-of-the-mill PropertyGrid.

If for some reason you are unable to change a PropertyGrid out, you can use the ShinyDesign.Design.TypeDescriptorSurrogate class.  It gives you *almost* all of the benefits of the PropertyGridEx class - the key difference being that multiple property tabs are not available in this situation.  You wrap the object being inspected in a new instance of TypeDescriptorSurrogate, and assign the surrogate object as the SelectedObject of the property grid.  The actual object is updated, just as if you were working with the PropertyGridEx.

If you plan on using this in applications, I'd appreciate a nod, or at least an e-mail letting me know that you're using it and whether you found it helpful.  The license terms stipulate that my copyright notice must appear in source code redistributions, but not in binary redistributions, with the exception of the disclaimer of warranties (which must be included in all forms in some way).  Also, if you come across a bug, please drop me an e-mail so I can roll the fix into the main source tree.

Now that it's out, I'm not sure how much extra time I'll be putting into it, but I know that there are some updates I'd like to make to it, including the ability to inspect fields, methods, and events.  If possible, I'd like the ability to as closely mirror Hawkeye as possible, except that I don't really care to write the code to inject into other processes.  (This is where the multiple-property-tab idea came from in the first place).  But at the end of the day, I see the most use in this coming out of people who want to use it for their user configuration screens - that's why I built it in the first place.