哈希lib4csharp - 用c#写的综合散列图书馆

XOR-EL.

成员
加入
5月28日,2020年
消息
16
编程经验
3-5
哈希lib4csharp. 是一种全面易于使用的散列库,写在C#中。它提供了灵活的接口,使使用微风。散列可以单通或增量模式完成。它还提供了克隆每个哈希对象的内部状态的方法。
它提供 适配器 课程使其可以轻松可将其可插入接受标准.NET的方法 散列米, HMAC. 或者 衍生比斯 摘要基本课程可能适用。

使用库的所有功能都使用该库进行测试 纳尼特 framework.

该库因净标标2.1而构建。

*请注意,这是我的C#端口 哈希lib4pascal. 图书馆具有各种改进。

github存储库网址
哈希lib4csharp.
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+
@ xor-el :你为什么在这里定义自己的例外:
//github.com/Xor-el/HashLib4CSharp/blob/master/HashLib4CSharp/src/Utils/HashLibException.cs:
/*
(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
{ *                             HashLib4CSharp Library                              * }
{ *                      Copyright (c) 2020 Ugochukwu Mmaduekwe                     * }
{ *                 GitHub Profile URL <//github.com/Xor-el>                  * }

{ *  Distributed under the MIT software license, see the accompanying LICENSE file  * }
{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }

{ *                              Acknowledgements:                                  * }
{ *                                                                                 * }
{ *   This library was sponsored by Sphere 10 Software (//www.sphere10.com)   * }
{ *         for the purposes of supporting the XXX (//YYY) project.           * }
{ *                                                                                 * }
(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
*/

using System;

namespace HashLib4CSharp.Utils
{
    public class HashLibException : Exception
    {
        protected HashLibException(string message) : base(message)
        {
        }
    }

    public sealed class NullReferenceHashLibException : HashLibException
    {
        internal NullReferenceHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class InvalidOperationHashLibException : HashLibException
    {
        internal InvalidOperationHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class IndexOutOfRangeHashLibException : HashLibException
    {
        internal IndexOutOfRangeHashLibException(string message) : base(message)
        {
        }
    }

    public class ArgumentHashLibException : HashLibException
    {
        internal ArgumentHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class ArgumentInvalidHashLibException : ArgumentHashLibException
    {
        internal ArgumentInvalidHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class ArgumentNullHashLibException : ArgumentHashLibException
    {
        public ArgumentNullHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class ArgumentOutOfRangeHashLibException : ArgumentHashLibException
    {
        internal ArgumentOutOfRangeHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class NotImplementedHashLibException : HashLibException
    {
        internal NotImplementedHashLibException(string message) : base(message)
        {
        }
    }

    public class IOHashLibException : HashLibException
    {
        internal IOHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class FileNotFoundHashLibException : IOHashLibException
    {
        internal FileNotFoundHashLibException(string message) : base(message)
        {
        }
    }
}

当.NET框架 文件 says:
选择标准例外
当您必须抛出福彩12选5走势图时,您通常可以在.NET Framework中使用现有的福彩12选5走势图类型而不是实现自定义福彩12选5走势图。您应该在这两个条件下使用标准福彩12选5走势图类型:
  • 您正在抛出由使用错误引起的福彩12选5走势图(即,通过调用您的方法的开发人员制作的程序逻辑中的错误。 ......
  • 您正在处理可以使用现有的.NET Framework福彩12选5走势图传送给呼叫者的错误。您应该抛出最派生的例外。 ......

实现自定义例外
在以下情况下,使用现有的.NET Framework福彩12选5走势图来处理错误条件不足:

  • 当福彩12选5走势图反映出无法映射到现有的.NET Framework福彩12选5走势图的唯一程序错误。
  • 当福彩12选5走势图需要处理与适合现有的.NET Framework福彩12选5走势图的处理不同的处理时,或者福彩12选5走势图必须歧义类似的福彩12选5走势图。例如,如果你扔了一个 Argumentoutofrangeexception. 解析超出目标积分类型超出范围的字符串的数值表示时,您不希望为在调用方法时从呼叫者不提供适当的约束值的呼叫者使用相同的福彩12选5走势图。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+
Also there is a lot of use of unsafe pointers in the code. I've only done a brief scan so far, but I believe a majority of it can be replaced with using 跨度<byte> so that you don't have to compile with the unsafe flag on.
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+

XOR-EL.

成员
加入
5月28日,2020年
消息
16
编程经验
3-5
Also there is a lot of use of unsafe pointers in the code. I've only done a brief scan so far, but I believe a majority of it can be replaced with using 跨度<byte> so that you don't have to compile with the unsafe flag on.

使用跨度的示例的任何建议<byte>将是一个更好的合适而不是不安全的代码?
 

XOR-EL.

成员
加入
5月28日,2020年
消息
16
编程经验
3-5
@ xor-el :你为什么在这里定义自己的例外:
//github.com/Xor-el/HashLib4CSharp/blob/master/HashLib4CSharp/src/Utils/HashLibException.cs:
/*
(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
{ *                             HashLib4CSharp Library                              * }
{ *                      Copyright (c) 2020 Ugochukwu Mmaduekwe                     * }
{ *                 GitHub Profile URL <//github.com/Xor-el>                  * }

{ *  Distributed under the MIT software license, see the accompanying LICENSE file  * }
{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }

{ *                              Acknowledgements:                                  * }
{ *                                                                                 * }
{ *   This library was sponsored by Sphere 10 Software (//www.sphere10.com)   * }
{ *         for the purposes of supporting the XXX (//YYY) project.           * }
{ *                                                                                 * }
(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
*/

using System;

namespace HashLib4CSharp.Utils
{
    public class HashLibException : Exception
    {
        protected HashLibException(string message) : base(message)
        {
        }
    }

    public sealed class NullReferenceHashLibException : HashLibException
    {
        internal NullReferenceHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class InvalidOperationHashLibException : HashLibException
    {
        internal InvalidOperationHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class IndexOutOfRangeHashLibException : HashLibException
    {
        internal IndexOutOfRangeHashLibException(string message) : base(message)
        {
        }
    }

    public class ArgumentHashLibException : HashLibException
    {
        internal ArgumentHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class ArgumentInvalidHashLibException : ArgumentHashLibException
    {
        internal ArgumentInvalidHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class ArgumentNullHashLibException : ArgumentHashLibException
    {
        public ArgumentNullHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class ArgumentOutOfRangeHashLibException : ArgumentHashLibException
    {
        internal ArgumentOutOfRangeHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class NotImplementedHashLibException : HashLibException
    {
        internal NotImplementedHashLibException(string message) : base(message)
        {
        }
    }

    public class IOHashLibException : HashLibException
    {
        internal IOHashLibException(string message) : base(message)
        {
        }
    }

    public sealed class FileNotFoundHashLibException : IOHashLibException
    {
        internal FileNotFoundHashLibException(string message) : base(message)
        {
        }
    }
}

当.NET框架 文件 says:

非常感谢这个建议,将如图所示实现。
 

XOR-EL.

成员
加入
5月28日,2020年
消息
16
编程经验
3-5
@skydiver.,对于这样的案例

"您不想使用与在调用方法时从呼叫者提供适当的约束值的错误的错误"

您推荐什么类型的内置福彩12选5走势图?是"ArgumentException"好的这样的情景?
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+
我倾向于使用ArgumentException,并将关于参数无效的原因更详细的消息。只有在我需要让来电者能够区分多种不同类型的ArgumentException的情况下,这可能是我创建自定义福彩12选5走势图的单行代码可能导致的。这种自定义福彩12选5走势图仍然来自我能找到的最特定的内置,但我会创建一个子类,甚至进一步区分它。那种方式调用者可以选择捕获特定的福彩12选5走势图,或者他们可以选择捕获更通用的福彩12选5走势图。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+
你能否建议一个适当的评论标题样式。
我建议只是为了保持简单:
C#:
/*
HashLib4CSharp Library
Copyright (c) 2020 Ugochukwu Mmaduekwe
GitHub Profile URL <//github.com/Xor-el>

Distributed under the MIT software license, see the accompanying LICENSE file
or visit http://www.opensource.org/licenses/mit-license.php.

Acknowledgements:
This library was sponsored by Sphere 10 Software (//www.sphere10.com)
for the purposes of supporting the XXX (//YYY) project.
*/
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+
我看到你拿起了我昨晚发送的2次提取请求,就性能测试UI。我可能会尽快从你的回购中赶走。由于我的跨度实现失败,我一直在忙于调试CRC32代码。大约5分钟前才想到它。我很快就会在这里发布的不安全与跨度代码。
 

XOR-EL.

成员
加入
5月28日,2020年
消息
16
编程经验
3-5
我看到你拿起了我昨晚发送的2次提取请求,就性能测试UI。我可能会尽快从你的回购中赶走。由于我的跨度实现失败,我一直在忙于调试CRC32代码。大约5分钟前才想到它。我很快就会在这里发布的不安全与跨度代码。
是的,我做了,谢谢你,也非常感谢你的时间。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+
So here is a version of the CRC32 computation using 跨度<T>:
使用SPAN并在紧密循环内取出分支:
protected void LocalCrcCompute(uint[][] crcTable, byte[] data, int index, int length)
{
    if (data == null) throw new ArgumentNullHashLibException(nameof(data));
    Debug.Assert(index >= 0);
    Debug.Assert(length >= 0);
    Debug.Assert(index + length <= data.Length);

    const int unroll = 4;
    const int bytesAtOnce = 16 * unroll;

    var crc = ~CurrentCRC;
    var leftovers = BitConverter.IsLittleEndian ? ComputeLittleEndianBlocks()
        : ComputeBigEndianBlocks();

    // remaining 1 to 63 bytes (standard algorithm)
    foreach (var b in leftovers)
        crc = (crc >> 8) ^ crcTable[0][(crc & 0xFF) ^ b];

    CurrentCRC = ~crc;

    ReadOnlySpan<byte> ComputeLittleEndianBlocks()
    {
        var dataSpan = data.AsSpan(index, length);
        while (dataSpan.Length >= bytesAtOnce)
        {
            var dataUints = MemoryMarshal.Cast<byte, uint>(dataSpan);
            for (int unrolling = 0; unrolling < unroll; unrolling++, dataUints = dataUints.Slice(4))
            {
                var one = dataUints[0] ^ crc;
                var two = dataUints[1];
                var three = dataUints[2];
                var four = dataUints[3];

                crc = crcTable[0][(four >> 24) & 0xFF] ^
                    crcTable[1][(four >> 16) & 0xFF] ^
                    crcTable[2][(four >> 8) & 0xFF] ^
                    crcTable[3][four & 0xFF] ^
                    crcTable[4][(three >> 24) & 0xFF] ^
                    crcTable[5][(three >> 16) & 0xFF] ^
                    crcTable[6][(three >> 8) & 0xFF] ^
                    crcTable[7][three & 0xFF] ^
                    crcTable[8][(two >> 24) & 0xFF] ^
                    crcTable[9][(two >> 16) & 0xFF] ^
                    crcTable[10][(two >> 8) & 0xFF] ^
                    crcTable[11][two & 0xFF] ^
                    crcTable[12][(one >> 24) & 0xFF] ^
                    crcTable[13][(one >> 16) & 0xFF] ^
                    crcTable[14][(one >> 8) & 0xFF] ^
                    crcTable[15][one & 0xFF];
            }

            dataSpan = dataSpan.Slice(bytesAtOnce);
        }
        return dataSpan;
    }

    ReadOnlySpan<byte> ComputeBigEndianBlocks()
    {
        var dataSpan = data.AsSpan(index, length);
        while (dataSpan.Length >= bytesAtOnce)
        {
            var dataUints = MemoryMarshal.Cast<byte, uint>(dataSpan);
            for (int unrolling = 0; unrolling < unroll; unrolling++, dataUints = dataUints.Slice(4))
            {
                var one = dataUints[0] ^ Bits.ReverseBytesUInt32(crc);
                var two = dataUints[1];
                var three = dataUints[2];
                var four = dataUints[3];

                crc = crcTable[0][four & 0xFF] ^
                    crcTable[1][(four >> 8) & 0xFF] ^
                    crcTable[2][(four >> 16) & 0xFF] ^
                    crcTable[3][(four >> 24) & 0xFF] ^
                    crcTable[4][three & 0xFF] ^
                    crcTable[5][(three >> 8) & 0xFF] ^
                    crcTable[6][(three >> 16) & 0xFF] ^
                    crcTable[7][(three >> 24) & 0xFF] ^
                    crcTable[8][two & 0xFF] ^
                    crcTable[9][(two >> 8) & 0xFF] ^
                    crcTable[10][(two >> 16) & 0xFF] ^
                    crcTable[11][(two >> 24) & 0xFF] ^
                    crcTable[12][one & 0xFF] ^
                    crcTable[13][(one >> 8) & 0xFF] ^
                    crcTable[14][(one >> 16) & 0xFF] ^
                    crcTable[15][(one >> 24) & 0xFF];
            }

            dataSpan = dataSpan.Slice(bytesAtOnce);
        }
        return dataSpan;
    }
}

和 here is the original code that used unsafe pointers as well the branch inside the loop:
原始不安全代码与指针和分支内部紧密循环:
protected unsafe void LocalCrcCompute(uint[][] crcTable, byte[] data, int index,
                                      int length)
{
    if (data == null) throw new ArgumentNullHashLibException(nameof(data));
    Debug.Assert(index >= 0);
    Debug.Assert(length >= 0);
    Debug.Assert(index + length <= data.Length);

    const int unroll = 4;
    const int bytesAtOnce = 16 * unroll;
    var crc = ~CurrentCRC;

    fixed (byte* dataPtr = data)
    {
        var srcPtr = (uint*) (dataPtr + index);
        while (length >= bytesAtOnce)
        {
            var unrolling = 0;
            while (unrolling < unroll)
            {
                var one = Converters.ReadPCardinalAsUInt32(srcPtr)
                    ^ Converters.le2me_32(crc);
                srcPtr++;
                var two = Converters.ReadPCardinalAsUInt32(srcPtr);
                srcPtr++;
                var three = Converters.ReadPCardinalAsUInt32(srcPtr);
                srcPtr++;
                var four = Converters.ReadPCardinalAsUInt32(srcPtr);
                srcPtr++;

                if (BitConverter.IsLittleEndian)
                {
                    crc = crcTable[0][(four >> 24) & 0xFF] ^ crcTable[1]
                        [(four >> 16) & 0xFF] ^ crcTable[2][(four >> 8) & 0xFF]
                        ^ crcTable[3][four & 0xFF] ^ crcTable[4]
                        [(three >> 24) & 0xFF] ^ crcTable[5][(three >> 16) & 0xFF]
                        ^ crcTable[6][(three >> 8) & 0xFF] ^ crcTable[7]
                        [three & 0xFF] ^ crcTable[8][(two >> 24) & 0xFF] ^ crcTable
                        [9][(two >> 16) & 0xFF] ^ crcTable[10][(two >> 8) & 0xFF]
                        ^ crcTable[11][two & 0xFF] ^ crcTable[12][(one >> 24) & 0xFF]
                        ^ crcTable[13][(one >> 16) & 0xFF] ^ crcTable[14]
                        [(one >> 8) & 0xFF] ^ crcTable[15][one & 0xFF];
                }
                else
                {
                    crc = crcTable[0][four & 0xFF] ^ crcTable[1]
                        [(four >> 8) & 0xFF] ^ crcTable[2][(four >> 16) & 0xFF]
                        ^ crcTable[3][(four >> 24) & 0xFF] ^ crcTable[4]
                        [three & 0xFF] ^ crcTable[5][(three >> 8) & 0xFF] ^ crcTable
                        [6][(three >> 16) & 0xFF] ^ crcTable[7][(three >> 24) & 0xFF]
                        ^ crcTable[8][two & 0xFF] ^ crcTable[9][(two >> 8) & 0xFF]
                        ^ crcTable[10][(two >> 16) & 0xFF] ^ crcTable[11]
                        [(two >> 24) & 0xFF] ^ crcTable[12][one & 0xFF] ^ crcTable
                        [13][(one >> 8) & 0xFF] ^ crcTable[14][(one >> 16) & 0xFF]
                        ^ crcTable[15][(one >> 24) & 0xFF];
                }

                unrolling++;
            }

            length -= bytesAtOnce;
        }

        var srcPtr2 = (byte*) srcPtr;
        // remaining 1 to 63 bytes (standard algorithm)
        while (length != 0)
        {
            crc = (crc >> 8) ^ crcTable[0][(crc & 0xFF) ^ *srcPtr2];
            srcPtr2++;
            length--;
        }

        CurrentCRC = ~crc;
    }
}

在我古老的机器上,这是我得到的相对吞吐量:
C#:
657 659
684 680
676 677
2012年旧AMD系统上的时间:
                         Castagnoli PKZip  (in MB/s)
Original                    657      659
Original without branch     684      680
Span<T> without branch      676      677
 

XOR-EL.

成员
加入
5月28日,2020年
消息
16
编程经验
3-5
@skydiver. ,非常感谢这一点,从你的基准开始,我看到了 原件没有分支 比这更快 跨度<T> variant?
您可以分享代码的任何机会 原件没有分支 请?
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+
Yes, it is faster, but also more complex. Its still uses unsafe pointers. The reason I put in that statistic there was to show that using the 跨度<T> lets you have safer code, but the performance penalty is not that big.

请参阅拉请求#4。相关代码是:
C#:
protected unsafe void LocalCrcCompute(uint[][] crcTable, byte[] data, int index,
                                      int length)
{
    if (data == null) throw new ArgumentNullException(nameof(data));
    Debug.Assert(index >= 0);
    Debug.Assert(length >= 0);
    Debug.Assert(index + length <= data.Length);

    const int unroll = 4;
    const int bytesAtOnce = 16 * unroll;
    var crc = ~CurrentCRC;

    if (BitConverter.IsLittleEndian)
        ComputeLittleEndianBlocks();
    else
        ComputeBigEndianBlocks();

    CurrentCRC = ~crc;

    void ComputeLittleEndianBlocks()
    {
        fixed (byte* dataPtr = data)
        {
            var srcPtr = (uint*)(dataPtr + index);
            while (length >= bytesAtOnce)
            {
                var unrolling = 0;
                while (unrolling < unroll)
                {
                    var one = Converters.ReadPCardinalAsUInt32(srcPtr) ^ crc;
                    srcPtr++;
                    var two = Converters.ReadPCardinalAsUInt32(srcPtr);
                    srcPtr++;
                    var three = Converters.ReadPCardinalAsUInt32(srcPtr);
                    srcPtr++;
                    var four = Converters.ReadPCardinalAsUInt32(srcPtr);
                    srcPtr++;

                    crc = crcTable[0][(four >> 24) & 0xFF] ^ crcTable[1]
                        [(four >> 16) & 0xFF] ^ crcTable[2][(four >> 8) & 0xFF]
                        ^ crcTable[3][four & 0xFF] ^ crcTable[4]
                        [(three >> 24) & 0xFF] ^ crcTable[5][(three >> 16) & 0xFF]
                        ^ crcTable[6][(three >> 8) & 0xFF] ^ crcTable[7]
                        [three & 0xFF] ^ crcTable[8][(two >> 24) & 0xFF] ^ crcTable
                        [9][(two >> 16) & 0xFF] ^ crcTable[10][(two >> 8) & 0xFF]
                        ^ crcTable[11][two & 0xFF] ^ crcTable[12][(one >> 24) & 0xFF]
                        ^ crcTable[13][(one >> 16) & 0xFF] ^ crcTable[14]
                        [(one >> 8) & 0xFF] ^ crcTable[15][one & 0xFF];

                    unrolling++;
                }

                length -= bytesAtOnce;
            }

            var srcPtr2 = (byte*)srcPtr;
            // remaining 1 to 63 bytes (standard algorithm)
            while (length != 0)
            {
                crc = (crc >> 8) ^ crcTable[0][(crc & 0xFF) ^ *srcPtr2];
                srcPtr2++;
                length--;
            }
        }
    }


    void ComputeBigEndianBlocks()
    {
        fixed (byte* dataPtr = data)
        {
            var srcPtr = (uint*)(dataPtr + index);
            while (length >= bytesAtOnce)
            {
                var unrolling = 0;
                while (unrolling < unroll)
                {
                    var one = Converters.ReadPCardinalAsUInt32(srcPtr) ^ Bits.ReverseBytesUInt32(crc);
                    srcPtr++;
                    var two = Converters.ReadPCardinalAsUInt32(srcPtr);
                    srcPtr++;
                    var three = Converters.ReadPCardinalAsUInt32(srcPtr);
                    srcPtr++;
                    var four = Converters.ReadPCardinalAsUInt32(srcPtr);
                    srcPtr++;

                    crc = crcTable[0][four & 0xFF] ^ crcTable[1]
                        [(four >> 8) & 0xFF] ^ crcTable[2][(four >> 16) & 0xFF]
                        ^ crcTable[3][(four >> 24) & 0xFF] ^ crcTable[4]
                        [three & 0xFF] ^ crcTable[5][(three >> 8) & 0xFF] ^ crcTable
                        [6][(three >> 16) & 0xFF] ^ crcTable[7][(three >> 24) & 0xFF]
                        ^ crcTable[8][two & 0xFF] ^ crcTable[9][(two >> 8) & 0xFF]
                        ^ crcTable[10][(two >> 16) & 0xFF] ^ crcTable[11]
                        [(two >> 24) & 0xFF] ^ crcTable[12][one & 0xFF] ^ crcTable
                        [13][(one >> 8) & 0xFF] ^ crcTable[14][(one >> 16) & 0xFF]
                        ^ crcTable[15][(one >> 24) & 0xFF];

                    unrolling++;
                }

                length -= bytesAtOnce;
            }

            var srcPtr2 = (byte*)srcPtr;
            // remaining 1 to 63 bytes (standard algorithm)
            while (length != 0)
            {
                crc = (crc >> 8) ^ crcTable[0][(crc & 0xFF) ^ *srcPtr2];
                srcPtr2++;
                length--;
            }
        }
    }
}
 

XOR-EL.

成员
加入
5月28日,2020年
消息
16
编程经验
3-5
@skydiver.,好的,我看到了,感谢您的拉出请求,我将合并拉出请求,因为我将为这种情况有利。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,901
地点
切萨皮克,va.
编程经验
10+
没问题。这是你的图书馆。当有人讨论如何使用您的图书馆导致缓冲区覆盖或提升有人报告时,我猜你只会处理任何情况。表现是国王,这就是为什么我们仍然以C和C ++这样的语言编程......安全性,Smecurity ......这是别人被盗或机器所拥有的别人的身份......
 
最佳 底部