YZMHelper.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /******************************************************************************
  2. * 作者: 季健国
  3. * 创建时间: 2012/6/6 22:24:27
  4. *
  5. *
  6. ******************************************************************************/
  7. using System;
  8. using System.Web;
  9. using System.Drawing;
  10. using System.Security.Cryptography;
  11. namespace Ant.Service.Common
  12. {
  13. /// <summary>
  14. /// 验证码类
  15. /// </summary>
  16. public class Rand
  17. {
  18. #region 生成随机数字
  19. /// <summary>
  20. /// 生成随机数字
  21. /// </summary>
  22. /// <param name="length">生成长度</param>
  23. public static string Number(int Length)
  24. {
  25. return Number(Length, false);
  26. }
  27. /// <summary>
  28. /// 生成随机数字
  29. /// </summary>
  30. /// <param name="Length">生成长度</param>
  31. /// <param name="Sleep">是否要在生成前将当前线程阻止以避免重复</param>
  32. public static string Number(int Length, bool Sleep)
  33. {
  34. if (Sleep) System.Threading.Thread.Sleep(3);
  35. string result = "";
  36. System.Random random = new Random();
  37. for (int i = 0; i < Length; i++)
  38. {
  39. result += random.Next(10).ToString();
  40. }
  41. return result;
  42. }
  43. #endregion
  44. #region 生成随机字母与数字
  45. /// <summary>
  46. /// 生成随机字母与数字
  47. /// </summary>
  48. /// <param name="IntStr">生成长度</param>
  49. public static string Str(int Length)
  50. {
  51. return Str(Length, false);
  52. }
  53. /// <summary>
  54. /// 生成随机字母与数字
  55. /// </summary>
  56. /// <param name="Length">生成长度</param>
  57. /// <param name="Sleep">是否要在生成前将当前线程阻止以避免重复</param>
  58. public static string Str(int Length, bool Sleep)
  59. {
  60. if (Sleep) System.Threading.Thread.Sleep(3);
  61. char[] Pattern = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
  62. string result = "";
  63. int n = Pattern.Length;
  64. System.Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
  65. for (int i = 0; i < Length; i++)
  66. {
  67. int rnd = random.Next(0, n);
  68. result += Pattern[rnd];
  69. }
  70. return result;
  71. }
  72. #endregion
  73. #region 生成随机纯字母随机数
  74. /// <summary>
  75. /// 生成随机纯字母随机数
  76. /// </summary>
  77. /// <param name="IntStr">生成长度</param>
  78. public static string Str_char(int Length)
  79. {
  80. return Str_char(Length, false);
  81. }
  82. /// <summary>
  83. /// 生成随机纯字母随机数
  84. /// </summary>
  85. /// <param name="Length">生成长度</param>
  86. /// <param name="Sleep">是否要在生成前将当前线程阻止以避免重复</param>
  87. public static string Str_char(int Length, bool Sleep)
  88. {
  89. if (Sleep) System.Threading.Thread.Sleep(3);
  90. char[] Pattern = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
  91. string result = "";
  92. int n = Pattern.Length;
  93. System.Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
  94. for (int i = 0; i < Length; i++)
  95. {
  96. int rnd = random.Next(0, n);
  97. result += Pattern[rnd];
  98. }
  99. return result;
  100. }
  101. #endregion
  102. }
  103. /// <summary>
  104. /// 验证图片类
  105. /// </summary>
  106. public class YZMHelper
  107. {
  108. #region 私有字段
  109. private string text;
  110. private Bitmap image;
  111. //private int letterCount = 4; //验证码位数
  112. private int letterWidth = 16; //单个字体的宽度范围
  113. private int letterHeight = 20; //单个字体的高度范围
  114. private static byte[] randb = new byte[4];
  115. private static RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
  116. private Font[] fonts =
  117. {
  118. new Font(new FontFamily("Times New Roman"),10 +Next(1),System.Drawing.FontStyle.Regular),
  119. new Font(new FontFamily("Georgia"), 10 + Next(1),System.Drawing.FontStyle.Regular),
  120. new Font(new FontFamily("Arial"), 10 + Next(1),System.Drawing.FontStyle.Regular),
  121. new Font(new FontFamily("Comic Sans MS"), 10 + Next(1),System.Drawing.FontStyle.Regular)
  122. };
  123. #endregion
  124. #region 公有属性
  125. /// <summary>
  126. /// 验证码
  127. /// </summary>
  128. public string Text
  129. {
  130. get { return this.text; }
  131. }
  132. /// <summary>
  133. /// 验证码图片
  134. /// </summary>
  135. public Bitmap Image
  136. {
  137. get { return this.image; }
  138. }
  139. #endregion
  140. #region 构造函数
  141. public YZMHelper()
  142. {
  143. //HttpContext.Current.Response.Expires = 0;
  144. //HttpContext.Current.Response.Buffer = true;
  145. //HttpContext.Current.Response.ExpiresAbsolute = DateTime.Now.AddSeconds(-1);
  146. //HttpContext.Current.Response.AddHeader("pragma", "no-cache");
  147. //HttpContext.Current.Response.CacheControl = "no-cache";
  148. this.text = Rand.Number(4);
  149. CreateImage();
  150. }
  151. #endregion
  152. #region 私有方法
  153. /// <summary>
  154. /// 获得下一个随机数
  155. /// </summary>
  156. /// <param name="max">最大值</param>
  157. private static int Next(int max)
  158. {
  159. rand.GetBytes(randb);
  160. int value = BitConverter.ToInt32(randb, 0);
  161. value = value % (max + 1);
  162. if (value < 0) value = -value;
  163. return value;
  164. }
  165. /// <summary>
  166. /// 获得下一个随机数
  167. /// </summary>
  168. /// <param name="min">最小值</param>
  169. /// <param name="max">最大值</param>
  170. private static int Next(int min, int max)
  171. {
  172. int value = Next(max - min) + min;
  173. return value;
  174. }
  175. #endregion
  176. #region 公共方法
  177. /// <summary>
  178. /// 绘制验证码
  179. /// </summary>
  180. public void CreateImage()
  181. {
  182. int int_ImageWidth = this.text.Length * letterWidth;
  183. Bitmap image = new Bitmap(int_ImageWidth, letterHeight);
  184. Graphics g = Graphics.FromImage(image);
  185. g.Clear(Color.White);
  186. for (int i = 0; i < 2; i++)
  187. {
  188. int x1 = Next(image.Width - 1);
  189. int x2 = Next(image.Width - 1);
  190. int y1 = Next(image.Height - 1);
  191. int y2 = Next(image.Height - 1);
  192. g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
  193. }
  194. int _x = -12, _y = 0;
  195. for (int int_index = 0; int_index < this.text.Length; int_index++)
  196. {
  197. _x += Next(12, 16);
  198. _y = Next(-2, 2);
  199. string str_char = this.text.Substring(int_index, 1);
  200. str_char = Next(1) == 1 ? str_char.ToLower() : str_char.ToUpper();
  201. Brush newBrush = new SolidBrush(GetRandomColor());
  202. Point thePos = new Point(_x, _y);
  203. g.DrawString(str_char, fonts[Next(fonts.Length - 1)], newBrush, thePos);
  204. }
  205. for (int i = 0; i < 10; i++)
  206. {
  207. int x = Next(image.Width - 1);
  208. int y = Next(image.Height - 1);
  209. image.SetPixel(x, y, Color.FromArgb(Next(0, 255), Next(0, 255), Next(0, 255)));
  210. }
  211. image = TwistImage(image, true, Next(1, 3), Next(4, 6));
  212. g.DrawRectangle(new Pen(Color.LightGray, 1), 0, 0, int_ImageWidth - 1, (letterHeight - 1));
  213. this.image = image;
  214. }
  215. /// <summary>
  216. /// 字体随机颜色
  217. /// </summary>
  218. public Color GetRandomColor()
  219. {
  220. Random RandomNum_First = new Random((int)DateTime.Now.Ticks);
  221. System.Threading.Thread.Sleep(RandomNum_First.Next(50));
  222. Random RandomNum_Sencond = new Random((int)DateTime.Now.Ticks);
  223. int int_Red = RandomNum_First.Next(180);
  224. int int_Green = RandomNum_Sencond.Next(180);
  225. int int_Blue = (int_Red + int_Green > 300) ? 0 : 400 - int_Red - int_Green;
  226. int_Blue = (int_Blue > 255) ? 255 : int_Blue;
  227. return Color.FromArgb(int_Red, int_Green, int_Blue);
  228. }
  229. /// <summary>
  230. /// 正弦曲线Wave扭曲图片
  231. /// </summary>
  232. /// <param name="srcBmp">图片路径</param>
  233. /// <param name="bXDir">如果扭曲则选择为True</param>
  234. /// <param name="nMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
  235. /// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
  236. public System.Drawing.Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
  237. {
  238. double PI = 6.283185307179586476925286766559;
  239. Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
  240. Graphics graph = Graphics.FromImage(destBmp);
  241. graph.FillRectangle(new SolidBrush(Color.White), 0, 0, destBmp.Width, destBmp.Height);
  242. graph.Dispose();
  243. double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
  244. for (int i = 0; i < destBmp.Width; i++)
  245. {
  246. for (int j = 0; j < destBmp.Height; j++)
  247. {
  248. double dx = 0;
  249. dx = bXDir ? (PI * (double)j) / dBaseAxisLen : (PI * (double)i) / dBaseAxisLen;
  250. dx += dPhase;
  251. double dy = Math.Sin(dx);
  252. int nOldX = 0, nOldY = 0;
  253. nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
  254. nOldY = bXDir ? j : j + (int)(dy * dMultValue);
  255. Color color = srcBmp.GetPixel(i, j);
  256. if (nOldX >= 0 && nOldX < destBmp.Width
  257. && nOldY >= 0 && nOldY < destBmp.Height)
  258. {
  259. destBmp.SetPixel(nOldX, nOldY, color);
  260. }
  261. }
  262. }
  263. srcBmp.Dispose();
  264. return destBmp;
  265. }
  266. #endregion
  267. }
  268. }