.NET 中 C#中的MD5

C# 中的 System.Security.Cryptography.MD5 只提供返回 hash 字节数组的方法,而像 PHP 的 md5 函数缺省返回的都是长度为32的16进制字符串(到了 php5 之后才增加了可选参数允许调用者得到长度为16的二进制数据)。

using System.Text;

namespace flyy.info
{
public class MD5
{
// 格式化md5 hash 字节数组所用的格式(两位小写16进制数字)
private static readonly string m_strHexFormat = "x2";
private MD5() { }
/// <summary>
/// 使用当前缺省的字符编码对字符串进行加密
/// </summary>
/// <param name="str">需要进行md5演算的字符串</param>
/// <returns>用小写字母表示的32位16进制数字字符串</returns>
public static string md5(string str)
{
return (string)md5(str, false, Encoding.Default);
}
/// <summary>
/// 对字符串进行md5 hash计算
/// </summary>
/// <param name="str">需要进行md5演算的字符串</param>
/// <param name="raw_output">
/// false则返回经过格式化的加密字符串(等同于 string md5(string) )
/// true则返回原始的md5 hash 长度16 的 byte[] 数组
/// </param>
/// <returns>
/// byte[] 数组或者经过格式化的 string 字符串
/// </returns>
public static object md5(string str, bool raw_output)
{
return md5(str, raw_output, Encoding.Default);
}
/// <summary>
/// 对字符串进行md5 hash计算
/// </summary>
/// <param name="str">需要进行md5演算的字符串</param>
/// <param name="raw_output">
/// false则返回经过格式化的加密字符串(等同于 string md5(string) )
/// true则返回原始的md5 hash 长度16 的 byte[] 数组
/// </param>
/// <param name="charEncoder">
/// 用来指定对输入字符串进行编解码的 Encoding 类型,
/// 当输入字符串中包含多字节文字(比如中文)的时候
/// 必须保证进行匹配的 md5 hash 所使用的字符编码相同,
/// 否则计算出来的 md5 将不匹配。
/// </param>
/// <returns>
/// byte[] 数组或者经过格式化的 string 字符串
/// </returns>
public static object md5(string str, bool raw_output,
Encoding charEncoder)
{
if (!raw_output)
return md5str(str, charEncoder);
else
return md5raw(str, charEncoder);
}

/// <summary>
/// 使用当前缺省的字符编码对字符串进行加密
/// </summary>
/// <param name="str">需要进行md5演算的字符串</param>
/// <returns>用小写字母表示的32位16进制数字字符串</returns>
protected static string md5str(string str)
{
return md5str(str, Encoding.Default);
}
/// <summary>
/// 对字符串进行md5加密
/// </summary>
/// <param name="str">需要进行md5演算的字符串</param>
/// <param name="charEncoder">
/// 指定对输入字符串进行编解码的 Encoding 类型
/// </param>
/// <returns>用小写字母表示的32位16进制数字字符串</returns>
protected static string md5str(string str, Encoding charEncoder)
{
byte[] bytesOfStr = md5raw(str, charEncoder);
int bLen = bytesOfStr.Length;
StringBuilder pwdBuilder = new StringBuilder(32);
for (int i = 0; i < bLen; i++ )
{
pwdBuilder.Append(bytesOfStr[i].ToString(m_strHexFormat));
}
return pwdBuilder.ToString();
}
/// <summary>
/// 使用当前缺省的字符编码对字符串进行加密
/// </summary>
/// <param name="str">需要进行md5演算的字符串</param>
/// <returns>长度16 的 byte[] 数组</returns>
protected static byte[] md5raw(string str)
{
return md5raw(str, Encoding.Default);
}
/// <summary>
/// 对字符串进行md5加密
/// </summary>
/// <param name="str">需要进行md5演算的字符串</param>
/// <param name="charEncoder">
/// 指定对输入字符串进行编解码的 Encoding 类型
/// </param>
/// <returns>长度16 的 byte[] 数组</returns>
protected static byte[] md5raw(string str, Encoding charEncoder)
{
System.Security.Cryptography.MD5 md5 =
System.Security.Cryptography.MD5.Create();
return md5.ComputeHash(charEncoder.GetBytes(str));
}
}
}

最优化WPF 3D性能(基于“Tier-2”硬件)

开发人员在应用程序中使用Windows Presentation Foundation来构建大量的3D控件、包含3D场景时,常常会遇到如何优化其性能的问题。WPF 3D组的几个成员提供了一个影响应用程序性能的3D类和属性的列表。当我们使用她们来优化应用程序性能时应该遵从这些建议。
本 随笔假定你深刻的理解了WPF 3D API。不熟悉这些API的用户在使用这些建议之前应该首先阅读WPF SDK文档。本随笔中提出的建议只适用于“Tier-2”的视频硬件(通常是指支持象素Shader 2.0和顶点Shader 2.0的硬件)。为了简洁,本随笔进行适当的总结,因此真正理解掌握她们并不简单。
性能影响级:高
属性
建议
Brush
Brush速度(从快到慢):
SolidColorBrush
LinearGradientBrush
ImageBrush
DrawingBrush(缓存的)
VisualBrush(缓存的)
RadialGradientBrush
DrawingBrush(未缓存的)
VisualBrush(未缓存的)
Viewport3D.ClipToBounds
在明确不需要把Viewport3D的内容剪切到Viewport3D的矩形范围内时,应该把Viewport3D.ClipToBounds设置为false。WPF的反走样剪切非常慢,而且ClipToBounds默认是为true的。
Viewport3D.IsHitTestVisible
如果鼠标点击时不需要考虑Viewport3D的内容,Viewport3D.IsHitTestVisible应该设置为false。3D内容的点击测试是由软件实现的,在大的网格中非常慢。Viewport3D的IsHitTestVisible默认是为true的。
GeometryModel3D
只 有在需要不同的Materials或者Transforms时,才建立不同的模型。否则应该把多个GeometryModel3D实例用相同的 Materials和Transforms组合到一个更大的GeometryModel3D和MeshGeometry3D实例之中。
MeshGeometry3D
基于每帧来改变网格的不同顶点形成的网格动画在WPF不是很高效。在修改顶点时,为了减少对性能的影响,在执行每个顶点的修改之前应该从Visual树中Detach网格。在修改完成后,重新Attach到Visual树。同样,构建这样的动画时应该减小网格的大小。
3D反走样
为 了尽可能增加提交速度,可通过设置Attached属性RenderOptions.EdgeMode为Aliased来禁用 Multisampling。默认时,3D反走样在Windows XP被禁用,而在Windows Vista被启用,每个象素4个Samples。
Text
3D场景中的实时文本(比较在DrawingBrush或者VisualBrush中的文本就是实时的)通常非常缓慢。尝试使用文本的图像(通过RenderTargetBitmap)来代替她,除非你需要修改文本。
TileBrush
如果你必须要在3D场景中使用VisualBrush或者DrawingBrush(因为这种Brush的内容不是静态的),应该尝试缓存Brush(通过设置Attached属性RenderOptions.CachingHint为Cache实现)。
用CacheInvalidationThresholdMinimum、 CacheInvalidationThresholdMaximum设置无效放缩的最大、最小阀值。她能在场景中减小Brush重新生成的次数(甚至是 避免),同时保持我们需要的质量。默认时,DrawingBrush和VisualBrush都没有缓存,表示每次重画都必须重新生成画刷,而且整个内容 是被画到一个临时的Surface,最后再复制到目标Surface。
BitmapEffect
BitmapEffect强制其影响的所有内容都不能使用硬件加速来提交。如果需要最好的性能,请不要使用BitmapEffect。
 
性能影响级别:中
属性
建议
MeshGeometry3D
如果网格是通过共享顶点(而且这些顶点的位置、向量和纹理映射都相同),以邻接三角形的形式定义网格的,共享的顶点应该只定义一次,然后用索引MeshGeometry3D.TriangleIndices来定义三角形。
ImageBrush
当我们需要直接控制纹理大小时(比如在使用RenderTargetBitmap和/或者ImageBrush时),应该尽可能减小WPF纹理大小。注意低分辨率的纹理会降低显示质量。因此在质量和性能之间应该进行合理的选择。
Opacity
提 交半透明的3D内容时(比如反射),应该在Brush或者Materials上使用Opacity属性(通过Brush.Opacity或者 Materials.Opacity)而不是另外建立一个半透明的Viewport3D(使Viewport3D.Opacity < 1)。
Viewport3D
减少在场景中使用的Viewport3D的数量。把多个3D模型放在同一个Viewport3D之中,而不是为每个模型建立不同的Viewport3D。
Freezable
通常,重用MeshGeometry3D、GeometryModel3D、Brush和Materials很有好处。由于她们都从Freezable继承,都可以拥有多个父元素。
Brush
当Brush内容不改变时,用ImageBrush来代替VisualBrush和DrawingBrush。2D内容可以通过RenderTargetBitmap转换为Image,然后在ImageBursh中使用。
Light
光源速度(从快到慢):
Ambient
Directional
Point
Spot
MeshGeometry3D
尽量让网格大小满足这些条件:
MeshGeometry3D.Positions: 20,001个Point3D实例
MeshGeometry3D.TriangleIndices: 60,003个Int32实例
Materials
Materials速度(从快到慢):
EmissiveMaterials
DiffuseMaterials
SpecularMaterials
Brush
WPF 3D没有以相同的方式来选择忽略不可见的画刷(黑色的环境Brush、光亮画刷等等)。不要在我们的场景中使用她们。
MaterialsGroup
在MaterialsGroup中的每个Materials都引起另一个提交通道,因此包含多个Materials,即使是简单的Materials也会严重地增加GPU的填充指令。应该在MaterialsGroup尽可能减少Materials的数量。
 
性能影响级别:低
运算符
执行的运算
Transform3DGroup
当我们不需要动画或者数据绑定时,不要使用Transform组包含多个Transform。而是使用一个单独的MatrixTransform3D。
Light
在场景中减少光源的数量。太多的光源会强制WPF回退到软件提交实现。粗略的限制是110个DirectionalLights、70个PointLights或者40个SpotLights。
ModelVisual3D
应 该把静态对象单独放入一个ModelVisual3D实例。ModelVisual3D比GeometryModel3D更庞大,因为她缓存了变换的边 界。GeometryModel3D适合于模型。而ModelVisual3D适合于场景点。我们需要使用ModelVisual3D来把 GeometryModel3D实例(希望共享)放入场景之中。
Light
在场景中减少改变光源的次数。每次改变光源都强制重新生成Shader、重新编译。除非原来的配置已经存在(也就是Shader被缓存)。
MeshGeometry3D
为 了减少在WPF构造大量集合的时间,比如MeshGeometry3D的Position、Normals、TextureCoordinates和 TrangleIndices。应该在值写入前就改变集合的大小。如果可能,直接向集合的构造函数传入一个Array或者List。
 

作者:David Teitlebaum。感谢Chris RaubacherAnthony HodsdonJordan ParkerDaniel Lehenbauer