支持位移操作的环形字符串

引言

偶然看到一个加密问题,说要把若干个整数按二进制样式做成首尾衔接的环,然后要查找这个环中0和1的数目,还要确定某个二进制的片段在整个环里不重复。

我没有想得太细,只是想起了很早以前模拟大整数运算器时采取的一种原始方法—就是把数字转换为字符串,利用字符串拼接,人工地模拟二进制的位运算。于是想着做一个能支持位移的字符串,便有了下面这个小东西。

当然,这个结构很不完善,一方面是支持的位数有限制,二是取值也还有一些障碍,权当一乐了。

示例代码

一、将uint转换为32位的二进制字符串的扩展类

简单地利用“与”运算,按位生成uint值对应的二进制字符串。Convert.ToString(int value, int base)可以支持2/8/10/16四种进制。

public static class UIntToBinString
{   
    public static string ToBinString(this uint value)
    {
        StringBuilder result = new StringBuilder();
        for (int i = 0, mask = 1; i < 32; i++, mask <<= 1)
        {
            if ((value & mask) == mask)
                result.Insert(0, '1');
            else
                result.Insert(0, '0');
        }

        return result.ToString();
    }
}

二、对单个字符串实现位移的类

声明一个位移处理的委托ShiftHandler,方便之后的处理。

public class StringNode 
{
    private string _value;

    public string Value
    {
        get { return _value; }
    }

    public delegate void ShiftHandler(int bit, ref string segment);
    public ShiftHandler LeftShiftHandler;
    public ShiftHandler RightShiftHandler;

    private StringNode()
    {
        this.LoadDefaultHandler();
    }

    public StringNode(string value)
        : this()
    {
        Debug.Assert(!string.IsNullOrEmpty(value), "Ctor does not accept empty or null string as para.");
        this._value = value;
    }

    private void LeftShift(int bit, ref string segment)
    {
        Debug.Assert(bit > 0, "para bit must be greater than zero.");
        Debug.Assert(!string.IsNullOrEmpty(segment), "para segment can not be empty or null.");
        Debug.Assert(bit == segment.Length, "length of para segment does not equals to bit.");

        string temp = this._value;
        this._value = temp.Substring(bit) + segment;
        segment = temp.Substring(0, bit);
    }

    private void RightShift(int bit, ref string segment)
    {
        Debug.Assert(bit > 0, "para bit must be greater than zero.");
        Debug.Assert(!string.IsNullOrEmpty(segment), "para segment can not be empty or null.");
        Debug.Assert(bit == segment.Length, "length of para segment does not equals to bit.");

        string temp = this._value;
        this._value = segment + temp.Substring(0, temp.Length - bit);
        segment = temp.Substring(temp.Length - bit);
    }

    public void LoadDefaultHandler()
    {
        this.LeftShiftHandler = new ShiftHandler(this.LeftShift);
        this.RightShiftHandler = new ShiftHandler(this.RightShift);
    }
}

三、对前一个类StringNode的升级和再封装

把若干个字符串拼接起来,实现整体位移。

public class StringQueue : List<StringNode>
{
    public void LeftShift(int bit)
    {
        Debug.Assert(bit > 0, "para bit must be greater than zero.");
        string temp = this[0].Value.Substring(0, bit);
        this.AttachChain();
        this[0].LeftShiftHandler(bit, ref temp);
        this.DetachChain();
    }

    public void RightShift(int bit)
    {
        Debug.Assert(bit > 0, "para bit must be greater than zero.");
        string temp = this[this.Count-1].Value;
        temp = temp.Substring(temp.Length - bit);
        this.AttachChain();
        this[0].RightShiftHandler(bit, ref temp);
        this.DetachChain();
    }

    private void AttachChain()
    {    
        for (int i = 1; i < this.Count; i++)
        {
            this[0].LeftShiftHandler += this[i].LeftShiftHandler;
            this[0].RightShiftHandler += this[i].RightShiftHandler;
        }        
    }

    private void DetachChain()
    {
        this[0].LoadDefaultHandler();
    }

    public void DisplayValue()
    {
        Console.ForegroundColor = ConsoleColor.Yellow;

        foreach (StringNode node in this)
            Console.Write(node.Value);
        Console.WriteLine();

        Console.ForegroundColor = ConsoleColor.White;
    }
}

四、主程序示例

static void Main(string[] args)
{
    uint[] array = new uint[] { 1315, 34135, 133813, 80761 };
    StringQueue queue = new StringQueue();

    foreach (uint value in array)
        queue.Add(new StringNode(value.ToBinString()));

    Console.WriteLine("原始值");
    queue.DisplayValue();
    
    Console.WriteLine("右移6位");
    queue.RightShift(6);
    queue.DisplayValue();

    Console.WriteLine("左移11位");
    queue.LeftShift(11);
    queue.DisplayValue();

    Console.ReadLine();
}

五、运行结果

原始值
00000000000000000000101001000110000000000000000
10000101010101110000000000000010000101010110101
00000000000000010011101101111001
右移6位
11001000000000000000000000101001000110000000000
00000010000101010101110000000000000100000101010
11010100000000000000010011101101
左移11位
00000000000000010100111001000000000000000010000
10101111001000000000000001000001101010001100000
00000000001001110110101011100000
原文地址:https://www.cnblogs.com/Abbey/p/2107898.html