var number = 123456.789; console.log(new Intl.NumberFormat('en-IN', { maximumFractionDigits: 2 }).format(number));
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
Используйте класс System.Runtime.InteropServices.Marshal
:
String SecureStringToString(SecureString value) {
IntPtr valuePtr = IntPtr.Zero;
try {
valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
return Marshal.PtrToStringUni(valuePtr);
} finally {
Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
}
}
Если вы хотите избежать создания управляемого объекта строки, вы могу получить доступ к необработанным данным, используя Marshal.ReadInt16 (IntPtr, Int32)
:
void HandleSecureString(SecureString value) {
IntPtr valuePtr = IntPtr.Zero;
try {
valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
for (int i=0; i < value.Length; i++) {
short unicodeChar = Marshal.ReadInt16(valuePtr, i*2);
// handle unicodeChar
}
} finally {
Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
}
}
Я произошел от Этот ответ sclarke81. Мне нравится его ответ, и я использую производную, но sclarke81 имеет ошибку. У меня нет репутации, таким образом, я не могу прокомментировать. Проблема кажется достаточно небольшой, что она не гарантировала другой ответ, и я мог отредактировать ее. Таким образом, я сделал. Это было отклонено. Таким образом, теперь у нас есть другой ответ.
sclarke81 я надеюсь, что Вы видите это (в наконец):
Marshal.Copy(new byte[length], 0, insecureStringPointer, length);
должен быть:
Marshal.Copy(new byte[length * 2], 0, insecureStringPointer, length * 2);
И полный ответ с исправлением ошибки:
///
/// Allows a decrypted secure string to be used whilst minimising the exposure of the
/// unencrypted string.
///
/// Generic type returned by Func delegate.
/// The string to decrypt.
///
/// Func delegate which will receive the decrypted password as a string object
///
/// Result of Func delegate
///
/// This method creates an empty managed string and pins it so that the garbage collector
/// cannot move it around and create copies. An unmanaged copy of the the secure string is
/// then created and copied into the managed string. The action is then called using the
/// managed string. Both the managed and unmanaged strings are then zeroed to erase their
/// contents. The managed string is unpinned so that the garbage collector can resume normal
/// behaviour and the unmanaged string is freed.
///
public static T UseDecryptedSecureString(this SecureString secureString, Func action)
{
int length = secureString.Length;
IntPtr sourceStringPointer = IntPtr.Zero;
// Create an empty string of the correct size and pin it so that the GC can't move it around.
string insecureString = new string('\0', length);
var insecureStringHandler = GCHandle.Alloc(insecureString, GCHandleType.Pinned);
IntPtr insecureStringPointer = insecureStringHandler.AddrOfPinnedObject();
try
{
// Create an unmanaged copy of the secure string.
sourceStringPointer = Marshal.SecureStringToBSTR(secureString);
// Use the pointers to copy from the unmanaged to managed string.
for (int i = 0; i < secureString.Length; i++)
{
short unicodeChar = Marshal.ReadInt16(sourceStringPointer, i * 2);
Marshal.WriteInt16(insecureStringPointer, i * 2, unicodeChar);
}
return action(insecureString);
}
finally
{
// Zero the managed string so that the string is erased. Then unpin it to allow the
// GC to take over.
Marshal.Copy(new byte[length * 2], 0, insecureStringPointer, length * 2);
insecureStringHandler.Free();
// Zero and free the unmanaged string.
Marshal.ZeroFreeBSTR(sourceStringPointer);
}
}
///
/// Allows a decrypted secure string to be used whilst minimising the exposure of the
/// unencrypted string.
///
/// The string to decrypt.
///
/// Func delegate which will receive the decrypted password as a string object
///
/// Result of Func delegate
///
/// This method creates an empty managed string and pins it so that the garbage collector
/// cannot move it around and create copies. An unmanaged copy of the the secure string is
/// then created and copied into the managed string. The action is then called using the
/// managed string. Both the managed and unmanaged strings are then zeroed to erase their
/// contents. The managed string is unpinned so that the garbage collector can resume normal
/// behaviour and the unmanaged string is freed.
///
public static void UseDecryptedSecureString(this SecureString secureString, Action action)
{
UseDecryptedSecureString(secureString, (s) =>
{
action(s);
return 0;
});
}
}
Данг. Прямо после публикации я нашел ответ глубоко в этой статье . Но если кто-то знает, как получить доступ к неуправляемому, незашифрованному буферу IntPtr, который предоставляет этот метод, по одному байту за раз, чтобы мне не приходилось создавать из него управляемый строковый объект для поддержания высокого уровня безопасности, добавьте ответ. :)
static String SecureStringToString(SecureString value)
{
IntPtr bstr = Marshal.SecureStringToBSTR(value);
try
{
return Marshal.PtrToStringBSTR(bstr);
}
finally
{
Marshal.FreeBSTR(bstr);
}
}