YZMHelper.cs 10 KB

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