System.IO.Path.Populate83FileNameFromRandomBytes C# (CSharp) Méthode

Populate83FileNameFromRandomBytes() private static méthode

private static Populate83FileNameFromRandomBytes ( byte bytes, int byteCount, char chars, int charCount ) : void
bytes byte
byteCount int
chars char
charCount int
Résultat void
        private static unsafe void Populate83FileNameFromRandomBytes(byte* bytes, int byteCount, char* chars, int charCount)
        {
            Debug.Assert(bytes != null);
            Debug.Assert(chars != null);

            // This method requires bytes of length 8 and chars of length 12.
            Debug.Assert(byteCount == 8, $"Unexpected {nameof(byteCount)}");
            Debug.Assert(charCount == 12, $"Unexpected {nameof(charCount)}");

            byte b0 = bytes[0];
            byte b1 = bytes[1];
            byte b2 = bytes[2];
            byte b3 = bytes[3];
            byte b4 = bytes[4];

            // Consume the 5 Least significant bits of the first 5 bytes
            chars[0] = s_base32Char[b0 & 0x1F];
            chars[1] = s_base32Char[b1 & 0x1F];
            chars[2] = s_base32Char[b2 & 0x1F];
            chars[3] = s_base32Char[b3 & 0x1F];
            chars[4] = s_base32Char[b4 & 0x1F];

            // Consume 3 MSB of b0, b1, MSB bits 6, 7 of b3, b4
            chars[5] = s_base32Char[(
                    ((b0 & 0xE0) >> 5) |
                    ((b3 & 0x60) >> 2))];

            chars[6] = s_base32Char[(
                    ((b1 & 0xE0) >> 5) |
                    ((b4 & 0x60) >> 2))];

            // Consume 3 MSB bits of b2, 1 MSB bit of b3, b4
            b2 >>= 5;

            Debug.Assert(((b2 & 0xF8) == 0), "Unexpected set bits");

            if ((b3 & 0x80) != 0)
                b2 |= 0x08;
            if ((b4 & 0x80) != 0)
                b2 |= 0x10;

            chars[7] = s_base32Char[b2];

            // Set the file extension separator
            chars[8] = '.';

            // Consume the 5 Least significant bits of the remaining 3 bytes
            chars[9] = s_base32Char[(bytes[5] & 0x1F)];
            chars[10] = s_base32Char[(bytes[6] & 0x1F)];
            chars[11] = s_base32Char[(bytes[7] & 0x1F)];
        }

Usage Example

        private static unsafe string CreateTempSubdirectoryCore(string?prefix)
        {
            ValueStringBuilder builder = new ValueStringBuilder(stackalloc char[PathInternal.MaxShortPath]);

            Path.GetTempPath(ref builder);

            // ensure the base TEMP directory exists
            CreateDirectory(PathHelper.Normalize(ref builder));

            builder.Append(prefix);

            const int RandomFileNameLength  = 12; // 12 == 8 + 1 (for period) + 3
            int       initialTempPathLength = builder.Length;

            builder.EnsureCapacity(initialTempPathLength + RandomFileNameLength);

            // For generating random file names
            // 8 random bytes provides 12 chars in our encoding for the 8.3 name.
            const int RandomKeyLength = 8;
            byte *    pKey            = stackalloc byte[RandomKeyLength];

            // to avoid an infinite loop, only try as many as GetTempFileNameW will create
            const int MaxAttempts = ushort.MaxValue;
            int       attempts    = 0;

            while (attempts < MaxAttempts)
            {
                // simulate a call to Path.GetRandomFileName() without allocating an intermediate string
                Interop.GetRandomBytes(pKey, RandomKeyLength);
                Path.Populate83FileNameFromRandomBytes(pKey, RandomKeyLength, builder.RawChars.Slice(builder.Length, RandomFileNameLength));
                builder.Length += RandomFileNameLength;

                string path = PathHelper.Normalize(ref builder);

                bool directoryCreated = Interop.Kernel32.CreateDirectory(path, null);
                if (!directoryCreated)
                {
                    // in the off-chance that the directory already exists, try again
                    int error = Marshal.GetLastPInvokeError();
                    if (error == Interop.Errors.ERROR_ALREADY_EXISTS)
                    {
                        builder.Length = initialTempPathLength;
                        attempts++;
                        continue;
                    }

                    throw Win32Marshal.GetExceptionForWin32Error(error, path);
                }

                builder.Dispose();
                return(path);
            }

            throw new IOException(SR.IO_MaxAttemptsReached);
        }
All Usage Examples Of System.IO.Path::Populate83FileNameFromRandomBytes