G.

光's blog

 主界面

 

账号管理界面

服务器列表 ( 只在多区时显示 )

================================================================

  • 程序下载

下载地址(简/繁 双语言): http://60.aionchs.com/web/dlq/aion.zip
( 注: 切换语言修改 Language.ini 文件中的 lang 即可. )

安全软件扫描结果: http://www.virustotal.com/file-scan/report.html?id=add9831d4ef36ba2c722b12c56a7485efabe9bb0c636cf008994e6ebd1879e01-1281445741

 

  • 作者信息

作者: 李光

作者主页: http://www.lgblog.org

作者QQ: 860880076

 

 

  • 注意事项

LS 的端口一定要禁止外网访问 , 否则反外挂形同虚设.

在生成更新列表前请先改好你的登录器文件名, 生成后最好不要手动修改

 如果需要修改 请保证自动更新列表中的登录器文件名与你发给玩家的登录器文件名一致(大小写也要一致) 否则可能无法更新主程序自身.

请保证服务器的 6553 端口可被外网访问到, 此为 登陆器与反外挂网关之间的通信端口.

win2003企业版运行登陆器要关闭数据执行保护.或添加数据执行保护排除列表!

 

  • 超强功能

反外挂, 自动更新, 账号管理, 支持多区, 可自定义外挂特征 .

 

  • 注册说明

商业登陆器+商业合区软件+技术支持+永久免费更新=518

 不注册依然可以使用本登陆器 ( 主要功能不会受到任何影响 ),  免费版有弹窗广告 .

 作者QQ 860880076

  

  • 更新日记

—————————————–

10.08.20.1

1. 修复了 反外挂网关 无法多开的问题 . 请替换 “反外挂.exe” , 本次仅升级反外挂服务 因此登陆器版本号无变化 .

—————————————–

10.08.10.1

1. 解决了”卡巴斯基” 误报的问题 . 请替换 “登录器生成.exe” , 并重新生成你的登陆器 .

—————————————–

10.08.03.1

1. 解决了360误报 . 请替换 “登录器生成.exe” , 并重新生成你的登陆器 .

—————————————–

10.08.01.1

1. 修复了 10.07.29.1版 中出现的 BUG( 游戏停顿 ) .请替换 “登录器生成.exe” , 并重新生成你的登陆器 .

—————————————–

10.07.29.1

1. 更新了反外挂模块 . 请替换 “反外挂.exe”,“登录器生成.exe” , 并重新生成你的登陆器 .

—————————————–

10.07.21.2

1. 封了一个新出的的加速挂(三轮加速) . 请替换 “登录器生成.exe” , 并重新生成你的登陆器 .

—————————————–

10.07.21.1

1. 更新了登陆器主程序 .   请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.07.15.1

1. 更新了反外挂模块 .   请替换 “反外挂.exe”,“登录器生成.exe”  , 并重新生成你的登陆器 .
2. 修改了正版验证部分代码 , 如果生成器提示注册码过期 请联系我获取新的注册码(免费).

—————————————–

10.07.12.1

1. 解决了 10.07.10.1 版 金山毒霸误报的问题 .   请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.07.10.1

1. 更新了登陆器主程序 .   请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.07.07.1

1. 修正了更新文件生成器中的一处BUG ,  请替换 “更新文件生成器.exe” , 并重新生成你的自动更新文件.
(本次只更新了更新文件生成器因此登陆器版本号没有改变 不用重新生成登陆器.)

—————————————–

10.07.02.1

1. 修正了反外挂网关中的一处BUG ,  请替换 “反外挂.exe”.
(本次只更新了反外挂网关因此登陆器版本号没有改变 不用重新生成登陆器.)

—————————————–

10.06.28.1

1. 更新了登陆器主程序 , 解决 360 误报的问题 .   请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.26.1

1. 用 vc6 重新编写了登陆器主程序 , 误报几率大大降低 . 请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.16.1

1. 更新了反外挂模块 .  请替换 “反外挂.exe , “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.13.1

1. 更新了反外挂模块 .  请替换 “反外挂.exe , “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.12.1

1. 修复了登陆器主程序中的几处BUG .  请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.11.1

1. 修复了之前所有版本中的一处BUG .  请替换 “反外挂.exe , “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.10.1

1. 更新了反外挂模块 .  请替换 “反外挂.exe , “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.08.1

1. 加强了线程保护 防止玩家用工具结束反外挂线程 .  请替换 “反外挂.exe , “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.06.1

1. 修复了 10.06.04.2 版本某些玩家无法连接到服务器和游戏很卡的 BUG.  请替换 “反外挂.exe , “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.04.2

1. 发包限制改为 在反外挂网关中修改 ,  \config\server.ini 文件中设置 .  请替换 “反外挂.exe , “登录器生成.exe”  , 并重新生成你的登陆器 .
修改设置后必须重启反外挂网关 否则设置不会生效.

—————————————–

10.06.04.1

1. 反外挂网关增加了防御模式 , 网关在遭到攻击时请开启此功能  \config\server.ini 文件中的 fangyu 设为 1 即可 .  请替换 “反外挂.exe .

本次只更新了网关因此登陆器版本号没有改变.

—————————————–

10.06.02.1

1. 增强了发包限制的算法 , 请替换 “反外挂.exe”, “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.01.4

1. 增加了线程保护 禁止 XueTr 工具关闭登陆器线程 , 请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.01.3

1. 修正了 10.06.01.1~10.06.01.2 版严重误报的BUG , 请替换 “反外挂.exe”, “登录器生成.exe”  , 并重新生成你的登陆器 .
2. 去除了反外挂网关自动封IP的功能 , 请替换 “反外挂.exe”,“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.01.2

1. 修正了 10.06.01.1 中的一处错误 , 请替换 “反外挂.exe”, “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.06.01.1

1. 增加了客户端每秒发包数限制 ,  请替换 “反外挂.exe”, “登录器生成.exe”  , 并重新生成你的登陆器 .
2. 注册用户可自定义游戏结束后弹出的网页 , 请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.21.1

1. 解决了某些加速器隐藏后可用的问题 , 请替换 “反外挂.exe”,“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.13.1

1. 修复了生成器中的一处 BUG , 请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.12.2

1. 增加了 IAT Hook 的检测 , 请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.12.1

1. 更新了反外挂网关 , 请替换 “反外挂.exe”,“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.10.1

1. 更新了反外挂部分 , 请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.06.1

1. 增加了指定客户端文件的检测 , 请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.05.2

1. 修复了 10.05.05.1 版 加速挂依然可用的问题 , 请替换 “反外挂.exe” ,“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.05.1

1. 更新了反外挂部分 , 请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.05.04.1

1. 自动更新改为按下开始游戏后进行 , 请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.28.1

1. 更新了反外挂模块( DLL ) , 请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.27.1

1. 登陆器价格调整为 300元 , 请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.25.3

1. 反外挂服务增加了黑名单功能 ( 禁止黑名单中的IP连接 ) , 请替换 “反外挂.exe”,“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.25.2

1. 更新了合区工具 ( 修正了某些数据库数据错位的现象 ) .

—————————————–

10.04.25.1

1. 更新了登陆器界面 ( 去掉了带广告的龙影永恒皮肤 , 但作者还是龙影 ) , 请替换 “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.24.2

1. 更新了合区工具 ( 兼容多种服务端的数据库 ) .

—————————————–

10.04.24.1

1. 附加了一个合区工具 ( 测试 ) .

2. 修正了主程序中存在的一处 BUG , 请替换“登录器生成.exe”  , 并重新生成你的登陆器

—————————————–

10.04.23.1

1. 更新了反外挂模块 ( DLL ) ,  请替换 “反外挂.exe”,“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.20.2

1. 修复了繁体语言的一处翻译遗漏 ( 简体用户无需更新 ) ,  请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.20.1

1. 改用新的外挂扫描算法, 将CPU消耗降为 0% ,  请替换“登录器生成.exe”  , 并重新生成你的登陆器 .
2. 更新列表生成器 增加了保存设置 ,  请替换“更新文件生成器.exe”.

—————————————–

10.04.18.2

1. 修复了多开时重复更新的问题 ,  请替换“登录器生成.exe”  , 并重新生成你的登陆器 .
2. 修复了更新列表生成器在生成 bin32 时报错的问题 ,  请替换“更新文件生成器.exe”.

—————————————–

10.04.18.1

1. 再次优化外挂扫描算法 ,  请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.17.2

1. 优化了外挂扫描算法, 降低CPU消耗   ,  请替换“登录器生成.exe”  , 并重新生成你的登陆器 .
2. 登陆器进程不会被挂起 ( 冻结进程 )   ,  请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.17.1

1. 更新了登陆器主程序 ( 不会再替换官方登陆器 )  ,  请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.16.2

1. 更新了登陆器主程序  ,  请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.16.1

1. 更新了反外挂模块(DLL) 增强兼容性  ,  请替换“反外挂.exe”, “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.15.3

1. 增加了驻留进程 , 用于监控客户端目录  , 请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.15.2

1. 注册用户可自定义外挂特征 , 请替换“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.15.1

1. 更新了防外挂模块 ,  请替换  “反外挂.exe” ,“登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.14.1

1. 修复了 10.04.13.3~10.04.13.5 版本 误报外挂的 BUG ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.13.5

1. 免费用户可自由选择登陆器界面 ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.13.4

1. 修复了生成器上的一处乱码 ( 繁体系统中 ) ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.13.3

1. 更新了防外挂模块 ( DLL ) 加入网络时间校验, 可检测到大部分加速外挂 ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.13.2

1. 修复了 10.04.12.1~10.04.13.1 中出现的 BUG ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.13.1

1. 可自行选择是否使用新界面 ( 注册版功能 ) ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .
2. 可自定义游戏退出后弹出的页面 ( 注册版功能 ) ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.12.1

1. 重新设计了登陆器界面 ( 美工:龙影永恒 , QQ: 283390 <One.Piece> ) ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.11.1

1. 支持 简体/繁体 双语言 ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.10.1

1. 更新了登陆器主程序 增强兼容性 ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.08.1

1. 更新了防外挂模块( DLL ) 增强兼容性 ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .
2. 生成器增加了实时显示帮助信息的窗口 ,  请替换  “登录器生成.exe”  .

—————————————–

10.04.06.1

1. 更新了防外挂模块( DLL ) 增强兼容性 , 请替换 “登录器生成.exe” , 并重新生成你的登陆器 .

—————————————–

10.04.05.1

1. 增加了一些反调试代码 , 防止登陆器被破解  ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.03.2

1. 登陆器发现外挂 关闭游戏进程后 提示玩家为何关闭 , 请替换 “登录器生成.exe” , 并重新生成你的登陆器 .

—————————————–

10.04.03.1

1. 更新了防外挂模块( DLL ) 增强兼容性 ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.02.3

1. 修正了 10.04.02.1 ~ 10.04.02.2 提示 注入DLL 失败 的 问题 ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.02.2

1. 针对某登陆器的攻击行为 做出反击  ,  请替换  “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.04.02.1

1. 更新了反外挂部分  ,  请替换  “反外挂.exe” , “登录器生成.exe”  , 并重新生成你的登陆器 .

—————————————–

10.03.30.4

1. 修复了 10.03.30.1 ~ 10.03.30.3 版本无法保存客户端配置的BUG  ,  请替换 “登录器生成.exe”  .

—————————————–

10.03.30.3

1. 修复了客户端可以 本地修改技能的漏洞 client_skills.xml   ,  请替换 “登录器生成.exe”  .

—————————————–

10.03.30.2

1. 修复了 10.03.30.1 中 提示文件被修改的BUG , 请替换 “登录器生成.exe” .

—————————————–

10.03.30.1

1. 修复了之前版本依然可以用控制台漏洞的 BUG   ,  请替换 “登录器生成.exe”  .

—————————————–

10.03.27.1

1. 修正了上一版中 注册页面控件错位的BUG   ,  请替换 “登录器生成.exe”  .

—————————————–

10.03.26.2

1. 修正了上一版 在多区时 服务器显示维护的错误  ,  请替换 “登录器生成.exe”  .

—————————————–

10.03.26.1

1. 支持绑定域名  ,  请替换 “登录器生成.exe”  .

—————————————–

10.03.25.4

1. 更新了客户端搜索算法  ,  请替换 “登录器生成.exe”  .

—————————————–

10.03.25.2

1. 增加了服务器介绍设置 , 请替换 “登录器生成.exe” .

—————————————–

10.03.25.1

1. 美化了账号管理界面 , 请替换 “登录器生成.exe” .

—————————————–

10.03.24.4

1. 更新了反外挂服务 . 请替换 “反外挂.exe” , “登录器生成.exe”   必须重新生成您的登录器 .

—————————————–

10.03.24.3

1. 生成器增加了 保存配置, 读取配置 ( 注册版功能 ) . 请替换 “登录器生成.exe”  .

—————————————–

10.03.24.2

1. 美化了服务器选择界面 ( 注册版功能 ) . 请替换 “登录器生成.exe”  .

—————————————–

10.03.24.1

1. 支持多区, 可在列表中选择 ( 注册版功能 ) . 请替换 “登录器生成.exe”  .

—————————————–

10.03.23.1

1. 可关闭登陆器底部的版权信息 ( 注册版功能 ) . 请替换 “登录器生成.exe” .

—————————————–

10.03.22.2

1. 更新了客户端搜索算法. 请替换 “登录器生成.exe” .

—————————————–

10.03.22.1

1. 增加了自动寻找客户端的功能 ( 登录器不在游戏根目录时会自动寻找并将自身复制到游戏根目录内运行 ( 当找到游戏根目录时) ).
2. 增加了游戏退出后弹出网页的功能 ( 注册版功能 ).

本次更新请替换 “登录器生成.exe”  .

—————————————–

10.03.21.3

1. 修改了一些错误提示文本 .

—————————————–

10.03.21.2

1. 修正了 10.03.21.1 中存在的严重错误 , 请替换 “登录器生成.exe” .

—————————————–

10.03.21.1

1. 将 登录器, 配置文件, Hook.dll 合并为一个文件 ( 只需要将登录器发给玩家即可 ), 请用登录器生成器 生成你的登录器 .
2. 修改了账号服务中几处可能出现错误的代码. 请替换 “账号服务.exe”.
3. 可自定义 bin32 目录 , 请在生成登录器时 填写你自定义的 bin32 目录 ( 要保证此目录存在 )

—————————————–

10.03.20.1

1. 删除了几处不必要的代码( 提高兼容性 ) , 请替换 “aion.exe” .

—————————————–
2010/03/20

v1.4.2 以后将以日期的形式定义版本号. 例如 10.03.20.0 , 10.03.20 是更新日期, 后面的 .0 是指 当日第N次更新.

—————————————–

1.4.2

1. 美化了账号管理界面 . 请替换 “aion.exe” .

——————————————–

public class DesUtil {
byte[] bytekey;

public DesUtil(String strKey) {
this.bytekey = strKey.getBytes();
}

// 声明常量字节数组
private static final int[] IP = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52,
44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48,
40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35,
27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31,
23, 15, 7 }; // 64

private static final int[] IP_1 = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7,
47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45,
13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11,
51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49,
17, 57, 25 }; // 64

private static final int[] PC_1 = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50,
42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44,
36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6,
61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 }; // 56

private static final int[] PC_2 = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21,
10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47,
55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36,
29, 32 }; // 48

private static final int[] E = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9,
10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20,
21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 }; // 48

private static final int[] P = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23,
26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22,
11, 4, 25 }; // 32

private static final int[][][] S_Box = {
{ { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
{ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } },
{ // S_Box[1]
{ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
{ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
{ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
{ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } },
{ // S_Box[2]
{ 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
{ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
{ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
{ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } },
{ // S_Box[3]
{ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
{ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
{ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
{ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } },
{ // S_Box[4]
{ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
{ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
{ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
{ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } },
{ // S_Box[5]
{ 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
{ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
{ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
{ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } },
{ // S_Box[6]
{ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
{ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
{ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
{ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } },
{ // S_Box[7]
{ 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
{ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
{ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
{ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } } // S_Box[8]
};

private static final int[] LeftMove = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
2, 2, 2, 1 }; // 左移位置列表

private byte[] UnitDes(byte[] des_key, byte[] des_data, int flag) {
// 检测输入参数格式是否正确,错误直接返回空值(null)
if ((des_key.length != 8) || (des_data.length != 8)
|| ((flag != 1) && (flag != 0))) {
throw new RuntimeException(“Data Format Error !”);
}

int flags = flag;

// 二进制加密密钥
int[] keydata = new int[64];

// 二进制加密数据
int[] encryptdata = new int[64];

// 加密操作完成后的字节数组
byte[] EncryptCode = new byte[8];

// 密钥初试化成二维数组
int[][] KeyArray = new int[16][48];
// 将密钥字节数组转换成二进制字节数组
keydata = ReadDataToBirnaryIntArray(des_key);
// 将加密数据字节数组转换成二进制字节数组
encryptdata = ReadDataToBirnaryIntArray(des_data);
// 初试化密钥为二维密钥数组
KeyInitialize(keydata, KeyArray);
// 执行加密解密操作
EncryptCode = Encrypt(encryptdata, flags, KeyArray);

return EncryptCode;
}

// 初试化密钥数组
private void KeyInitialize(int[] key, int[][] keyarray) {
int i;
int j;
int[] K0 = new int[56];

// 特别注意:xxx[IP[i]-1]等类似变换
for (i = 0; i < 56; i++) {
K0[i] = key[PC_1[i] - 1]; // 密钥进行PC-1变换
}

for (i = 0; i < 16; i++) {
LeftBitMove(K0, LeftMove[i]);

// 特别注意:xxx[IP[i]-1]等类似变换
for (j = 0; j < 48; j++) {
keyarray[i][j] = K0[PC_2[j] - 1]; // 生成子密钥keyarray[i][j]
}
}
}

// 执行加密解密操作
private byte[] Encrypt(int[] timeData, int flag, int[][] keyarray) {
int i;
byte[] encrypt = new byte[8];
int flags = flag;
int[] M = new int[64];
int[] MIP_1 = new int[64];

// 特别注意:xxx[IP[i]-1]等类似变换
for (i = 0; i < 64; i++) {
M[i] = timeData[IP[i] - 1]; // 明文IP变换
}

if (flags == 1) { // 加密

for (i = 0; i < 16; i++) {
LoopF(M, i, flags, keyarray);
}
} else if (flags == 0) { // 解密

for (i = 15; i > -1; i–) {
LoopF(M, i, flags, keyarray);
}
}

for (i = 0; i < 64; i++) {
MIP_1[i] = M[IP_1[i] - 1]; // 进行IP-1运算
}

GetEncryptResultOfByteArray(MIP_1, encrypt);

// 返回加密数据
return encrypt;
}

private int[] ReadDataToBirnaryIntArray(byte[] intdata) {
int i;
int j;

// 将数据转换为二进制数,存储到数组
int[] IntDa = new int[8];

for (i = 0; i < 8; i++) {
IntDa[i] = intdata[i];

if (IntDa[i] < 0) {
IntDa[i] += 256;
IntDa[i] %= 256;
}
}

int[] IntVa = new int[64];

for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
IntVa[((i * 8) + 7) - j] = IntDa[i] % 2;
IntDa[i] = IntDa[i] / 2;
}
}

return IntVa;
}

private void LeftBitMove(int[] k, int offset) {
int i;

// 循环移位操作函数
int[] c0 = new int[28];
int[] d0 = new int[28];
int[] c1 = new int[28];
int[] d1 = new int[28];

for (i = 0; i < 28; i++) {
c0[i] = k[i];
d0[i] = k[i + 28];
}

if (offset == 1) {
for (i = 0; i < 27; i++) { // 循环左移一位
c1[i] = c0[i + 1];
d1[i] = d0[i + 1];
}

c1[27] = c0[0];
d1[27] = d0[0];
} else if (offset == 2) {
for (i = 0; i < 26; i++) { // 循环左移两位
c1[i] = c0[i + 2];
d1[i] = d0[i + 2];
}

c1[26] = c0[0];
d1[26] = d0[0];
c1[27] = c0[1];
d1[27] = d0[1];
}

for (i = 0; i < 28; i++) {
k[i] = c1[i];
k[i + 28] = d1[i];
}
}

private void LoopF(int[] M, int times, int flag, int[][] keyarray) {
int i;
int j;
int[] L0 = new int[32];
int[] R0 = new int[32];
int[] L1 = new int[32];
int[] R1 = new int[32];
int[] RE = new int[48];
int[][] S = new int[8][6];
int[] sBoxData = new int[8];
int[] sValue = new int[32];
int[] RP = new int[32];

for (i = 0; i < 32; i++) {
L0[i] = M[i]; // 明文左侧的初始化
R0[i] = M[i + 32]; // 明文右侧的初始化
}

for (i = 0; i < 48; i++) {
RE[i] = R0[E[i] - 1]; // 经过E变换扩充,由32位变为48位
RE[i] = RE[i] + keyarray[times][i]; // 与KeyArray[times][i]按位作不进位加法运算

if (RE[i] == 2) {
RE[i] = 0;
}
}

for (i = 0; i < 8; i++) { // 48位分成8组

for (j = 0; j < 6; j++) {
S[i][j] = RE[(i * 6) + j];
}

// 下面经过S盒,得到8个数
sBoxData[i] = S_Box[i][(S[i][0] << 1) + S[i][5]][(S[i][1] << 3)
+ (S[i][2] << 2) + (S[i][3] << 1) + S[i][4]];

// 8个数变换输出二进制
for (j = 0; j < 4; j++) {
sValue[((i * 4) + 3) - j] = sBoxData[i] % 2;
sBoxData[i] = sBoxData[i] / 2;
}
}

for (i = 0; i < 32; i++) {
RP[i] = sValue[P[i] - 1]; // 经过P变换
L1[i] = R0[i]; // 右边移到左边
R1[i] = L0[i] + RP[i];

if (R1[i] == 2) {
R1[i] = 0;
}

// 重新合成M,返回数组M
// 最后一次变换时,左右不进行互换。此处采用两次变换实现不变
if (((flag == 0) && (times == 0)) || ((flag == 1) && (times == 15))) {
M[i] = R1[i];
M[i + 32] = L1[i];
} else {
M[i] = L1[i];
M[i + 32] = R1[i];
}
}
}

private void GetEncryptResultOfByteArray(int[] data, byte[] value) {
int i;
int j;

// 将存储64位二进制数据的数组中的数据转换为八个整数(byte)
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
value[i] += (data[(i << 3) + j] << (7 - j));
}
}

for (i = 0; i < 8; i++) {
value[i] %= 256;

if (value[i] > 128) {
value[i] -= 255;
}
}
}

private byte[] ByteDataFormat(byte[] data, int flag) {
int len = data.length;
int padlen = 8 – (len % 8);
int newlen = len + padlen;
byte[] newdata = new byte[newlen];
System.arraycopy(data, 0, newdata, 0, len);

for (int i = len; i < newlen; i++)
newdata[i] = (byte) padlen;

return newdata;
}

public byte[] DesEncrypt(byte[] des_data, int flag) {
byte[] format_key = ByteDataFormat(bytekey, flag);
byte[] format_data = ByteDataFormat(des_data, flag);
int datalen = format_data.length;
int unitcount = datalen / 8;
byte[] result_data = new byte[datalen];

for (int i = 0; i < unitcount; i++) {
byte[] tmpkey = new byte[8];
byte[] tmpdata = new byte[8];
System.arraycopy(format_key, 0, tmpkey, 0, 8);
System.arraycopy(format_data, i * 8, tmpdata, 0, 8);

byte[] tmpresult = UnitDes(tmpkey, tmpdata, flag);
System.arraycopy(tmpresult, 0, result_data, i * 8, 8);
}

// 当前为解密过程,去掉加密时产生的填充位
byte[] decryptbytearray = null;

if (flag == 0) {
int total_len = datalen;
int delete_len = result_data[total_len - 8 - 1];
delete_len = ((delete_len >= 1) && (delete_len <= 8)) ? delete_len
: 0;
decryptbytearray = new byte[total_len - delete_len - 8];

boolean del_flag = true;

for (int k = 0; k < delete_len; k++) {
if (delete_len != result_data[total_len - 8 - (k + 1)])
del_flag = false;
}

if (del_flag == true) {
System.arraycopy(result_data, 0, decryptbytearray, 0, total_len
– delete_len – 8);
}
}
return (flag == 1) ? result_data : decryptbytearray;
}

public static void main(String[] args) {
String key = “12345678″;
String data = “Don’t tell anybody!!”;
DesUtil desUtil = new DesUtil(key);
System.err.println(“加密之前的数据:” + data);
// 加密后的byte型的密文
byte[] result = desUtil.DesEncrypt(data.getBytes(), 1);
System.err.println(“加密之后的数据:” + new String(result));
// 下句直接把byte类型的密文解密,能正确还原
System.err.println(“byte型乱码直接解密:”
+ new String(desUtil.DesEncrypt(result, 0)) + “(正确)”);

// 但先将byte型密文转成String,解密时再将String型转成byte转入时,不能正确还原
String str = new String(result);
System.err.println(“String型乱码解密:”
+ new String(desUtil.DesEncrypt(str.getBytes(), 0)) + “(错误)”);
}
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/myid/archive/2007/08/17/1748169.aspx

读书多、编程能力强并不意味着有水平和让人喜欢,关键是要自我修炼以期达到良好性情,
俗话说“做事先学做人”,我总结了日常工作、学习中的十个有益的做法,供大家参考:

争取做到:
一、守时:无论是开会、赴约,招人喜欢的人从不迟到。他们懂得,即使无意迟到,对其他准时到场的人来说,也是不尊重的表现。而且,如果可能的话,争取做到提前到达,正是所谓的“做事要有提前量”。要让被你等的人感到不好意思,同时也感到你的真诚。

二、谈吐有节:注意从不随便打断别人的谈话,总是先听完对方发言然后去交流或者补充对方的看法和意见。这点对于程序员来说,是比较难以做到的一点,大家在工作中往往会纠结于一个点而展开互不相让的争论,但切记要让别人把话说完,说清楚,这才是团队中最为有力的沟通方式之一。

三、态度和蔼: 在同别人谈话的时候,总是望着对方的眼睛,保持注意力集中,而不是翻东西、看报纸,心不在焉,显出一副无所谓的样子;或者使用这种态度来表达对对方观点的不认同,这就更是不可取了。

四、语言中肯: 避免高声喧哗,在待人接物上心平气和,以理服人,往往能取得满意的效果。

五、注意交谈技巧: 尊重他人的观点和看法,即使自己不能接受或明确同意,也不当着他人的面指责对方,而是陈述己见,讲清道理。

六、不自傲: 在与人交往相处时,从不强调个人特出的一面,也不有意表现自己的优越感。不用多说,程序员团体中有很多人都是这个的反面例子,有百害而无一益。

七、信守诺言: 即使遇到某种困难也不食言。自己谈出来的话,要竭尽全力去完成,身体力行是最好的诺言。对于程序员而言,信守诺言是一个基本的素养,很难想象一个不讲信用的人做出的工作会让人放心和信服。所以,一定要说到做到,否则就不要轻易的承诺别人。

八、关心他人: 不论何时何地,对同事、师长、朋友、上级、下级、以及其他接触的人员,总是表示出关心并给予最大的照顾和方便。不要小看这一点,做到了这一点,我相信你做出的程序会有相当的亲和力,会尽量的照顾到用户的需求和感受以及老板和同事的意愿。

九、大度: 与人相处胸襟开阔,不会为一点儿小事情和朋友、同事闹意见,甚至断绝来往。我对这点体会很深,在工作中,在我们的论坛上,都能看到反面的例子。做人与做事某种程度上是会传染的,你的大度会惠及整个团队的工作氛围,不要老是觉得只有自己这么大气,而周围的人却都那么小气,应该是保存着一个“岂能尽如人意,但求无愧我心”的思想,更应该像甘地,不轻易的改变自己,尽量磨砺自己澄澈的胸襟。

十、富有同情心: 在他人遇到某种不幸时,尽量给予同情和支持。不只是程序员,可以推而广之。

我想,大家都尽量的做一个有内涵的程序员、有教养的程序员、大气而有亲和力的程序员,这样的人有哪个团队会不欢迎呢?

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qter_wd007/archive/2010/07/23/5758975.aspx

DECLARE @Date  DATETIME
SET @Date=GETDATE()
–前一天,给定日期的前一天
SELECT DATEADD(DAY,-1,@Date) AS ‘前一天’
–后一天,给定日期的后一天
SELECT DATEADD(DAY,1,@Date) AS ‘后一天’
GO

–月初,计算给定日期所在月的第一天
–这个计算的技巧是先计算当前日期到“1900-01-01”的时间间隔数,然后把它加到“1900-01-01”上来获得特殊的日期,这个技巧可以用—来计算很多不同的日期。
DECLARE @Date  DATETIME
SET @Date=GETDATE()
SELECT DATEADD(MONTH,DATEDIFF(MONTH,’1900-01-01′,@Date),’1900-01-01′) AS ‘所在月的第一天’
–精简算法,根据SQL Server的时间表示方式可知,’1900-01-01′ 可以用0代替
SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0) AS ‘所在月的第一天’
–上面两种算法精确到天 时分秒均为00:00:00.000
–下面算法课以保留时分秒
–思路:用给定日期减去月第一天与给定日期差的天数
SELECT DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)
GO

–月末,计算给定日期所在月的最后一天
DECLARE @Date  DATETIME
SET @Date=GETDATE()
–思路:当前月的下一月1号在减1天
SELECT DATEADD(DAY,-1,DATEADD(MONTH,1+DATEDIFF(MONTH,’1900-01-01′,@Date),’1900-01-01′)) AS ‘所在月的最一天’
SELECT DATEADD(MONTH,1+DATEDIFF(MONTH,’1900-01-01′,@Date),’1900-01-01′)-1 AS ‘所在月的最一天’
–1900-01-01 用0代替
SELECT DATEADD(DAY,-1,DATEADD(MONTH,1+DATEDIFF(MONTH,0,@Date),0)) AS ‘所在月的最一天’
SELECT DATEADD(MONTH,1+DATEDIFF(MONTH,0,@Date),0)-1 AS ‘所在月的最一天’
–思路:与月初计算思路相同
SELECT DATEADD(MONTH,DATEDIFF(MONTH,’1989-12-31′,@Date),’1989-12-31′) AS ‘所在月的最一天’
–精简算法,’1989-12-31′ 用-1代替
SELECT DATEADD(MONTH,DATEDIFF(MONTH,-1,@Date),-1) AS ‘所在月的最一天’
–保留时分秒的算法
SELECT DATEADD(DAY,-1,DATEADD(MONTH,1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)))
GO

–其他月计算

–计算给定日期所在月的上月第一天
DECLARE @Date  DATETIME
SET @Date=GETDATE()
–当前月第一天减去一个月
SELECT DATEADD(MONTH,-1,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0)) AS ‘上月第一天’
–简化
SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,@Date)-1,0) AS ‘上月第一天’
–另一种当前月第一天算法
SELECT DATEADD(MONTH,-1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)) ‘上月第一天’
GO

–计算给定日期所在月的上月最后一天
DECLARE @Date  DATETIME
SET @Date=GETDATE()
–当前月第一天减去一天
SELECT DATEADD(DAY,-1,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0)) AS ‘上月最后一天’
–另一种当前月第一天算法
SELECT DATEADD(DAY,-1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)) ‘上月最后一天’
SELECT DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)-1 ‘上月最后一天’
–另一种算法,不能用当前月的最后一天加一个月,因为当前月可能是30天。
–例如 SELECT DATEADD(MONTH,1,’2010-06-30′) –结果是2010-07-30而不是2010-07-31,
–这也是月末算法采用下月第一天减1天计算的原因
–但是如果计算月是31天择无此问题
–例如 SELECT DATEADD(MONTH,1,’2010-05-31′) –结果是2010-06-30
–因此下面算法是正确的,-1 表示’1899-12-31 00:00:00.000′– SELECT CONVERT(DATETIME,-1)
SELECT DATEADD(MONTH,DATEDIFF(MONTH,-1,@Date)-1,-1)
–另一种当前月算法
SELECT DATEADD(DAY,-1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)) ‘上月最后一天’
–简化
SELECT DATEADD(DAY,0-DATEPART(DAY,@Date),@Date) ‘上月最后一天’
GO

–计算给定日期所在月的下月第一天
DECLARE @Date  DATETIME
SET @Date=GETDATE()
–当前月第一天加一个月
SELECT DATEADD(MONTH,1,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0)) AS ‘下月第一天’
–简化
SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,@Date)+1,0) AS ‘下月第一天’
–另一种当前月第一天算法
SELECT DATEADD(MONTH,1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)) ‘下月第一天’
GO

–计算给定日期所在月的下月最后一天
DECLARE @Date  DATETIME
SET @Date=GETDATE()
–当前月第一天加2个月再减去1天
SELECT DATEADD(DAY,-1,DATEADD(MONTH,2,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0))) AS ‘下月最后一天’
–简化
SELECT DATEADD(DAY,-1,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date)+2,0)) AS ‘下月最后一天’
SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,@Date)+2,0)-1 AS ‘下月最后一天’
–另一种算法
SELECT DATEADD(MONTH,DATEDIFF(MONTH,-1,@Date)+1,-1) ‘下月最后一天’
–另一种当前月第一天算法
SELECT DATEADD(DAY,-1,DATEADD(MONTH,2,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date))) ‘下月最后一天’
GO

–所在星期的第一天,计算给定日期所在星期的第1天(星期日为第一天)
DECLARE @Date  DATETIME
SET @Date= GETDATE()
–与SQL Server语言版本相关的算法
–思路:当前日期+星期日(每周的第1天)与当前日期的差的天数
–DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关
SET DATEFIRST 7 — 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)
SELECT DATEADD(WEEKDAY,1-DATEPART(WEEKDAY,@Date),@Date) AS ‘所在星期的第一天,星期日’
–星期日,与SQL Server语言版本或@@DATEFIRST无关
–’1989-12-31′ 是星期日,’1989-12-31′ 再加上(当前日期与1989-12-31差的星期数)个星期
SELECT DATEADD(WEEK,DATEDIFF(WEEK,-1,@Date),-1) AS ‘所在星期的星期日’
–或者
SELECT DATEADD(WEEK,DATEDIFF(WEEK,6,@Date),6) AS ‘所在星期的星期日’
GO

–所在星期的第二天,计算给定日期所在星期的第2天(星期日为第一天)
DECLARE @Date  DATETIME
SET @Date= GETDATE()
–思路:当前日期+星期一(每周的第2天)与当前日期的差的天数
–DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关
SET DATEFIRST 7 — 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)
SELECT DATEADD(DAY,2-DATEPART(WEEKDAY,@Date),@Date) AS ‘所在星期的第二天,星期一’
–星期一,与SQL Server语言版本或@@DATEFIRST无关
–’1900-01-01′ 是星期一,’1900-01-01′ 再加上(当前日期与1900-01-01差的星期数)个星期
SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,@Date),0) AS ‘所在星期的星期一’
GO

–上个星期第一天,计算给定日期所在星期的上一个星期日(星期日为第一天)
DECLARE @Date  DATETIME
SET @Date= GETDATE()
–思路:当前日志所在星期的星期日再减1周
–DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关
SET DATEFIRST 7 — 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)
SELECT DATEADD(WEEK,-1,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS ‘上个星期第一天,星期日’
–一周等于7天
SELECT DATEADD(DAY,-7,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS ‘上个星期第一天,星期日’
–简化
SELECT DATEADD(DAY,-6-DATEPART(WEEKDAY,@Date),@Date) AS ‘上个星期第一天,星期日’
–上个星期日,与SQL Server语言版本或@@DATEFIRST无关
SELECT DATEADD(WEEK,-1+DATEDIFF(WEEK,-1,@Date),-1) AS ‘上个星期日’
–或者
SELECT DATEADD(WEEK,DATEDIFF(WEEK,6,@Date),-1) AS ‘上个星期日’
GO

–下个星期第一天,计算给定日期所在星期的下一个星期日(星期日为第一天)
DECLARE @Date  DATETIME
SET @Date= GETDATE()
–思路:当前日志所在星期的星期日再加1周
–DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关
SET DATEFIRST 7 — 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)
SELECT DATEADD(WEEK,1,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS ‘下个星期第一天,星期日’
–一周等于7天
SELECT DATEADD(DAY,7,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS ‘下个星期第一天,星期日’
–简化
SELECT DATEADD(DAY,8-DATEPART(WEEKDAY,@Date),@Date) AS ‘下个星期第一天,星期日’
–下个星期日,与SQL Server语言版本或@@DATEFIRST无关
SELECT DATEADD(WEEK,1+DATEDIFF(WEEK,-1,@Date),-1) AS ‘下个星期日’
–或者
SELECT DATEADD(WEEK,DATEDIFF(WEEK,-1,@Date),6) AS ‘下个星期日’
GO

–判断给定日期是星期几
DECLARE @Date  DATETIME
SET @Date= GETDATE()
–DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关
SET DATEFIRST 7 — 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)
SELECT DATEPART(WEEKDAY,@Date) –返回值 1-星期日,2-星期一,3-星期二……7-星期六
–上面算法与SQL 语言版本或 @@DATEFIRST 相关
–下面算法与SQL Server语言版本或@@DATEFIRST无关
SELECT DATENAME(WEEKDAY,@Date) ‘星期’
GO

–年度计算
DECLARE @Date  DATETIME
SET @Date=GETDATE()
–年初,计算给定日期所在年的第一天
SELECT DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),0) AS ‘所在年的第一天’
–年末,计算给定日期所在年的最后一天
SELECT DATEADD(YEAR,DATEDIFF(YEAR,-1,@Date),-1) AS ‘所在年的最后一天’
–上一年年初,计算给定日期所在年的上一年的第一天
SELECT DATEADD(YEAR,DATEDIFF(YEAR,-0,@Date)-1,0) AS ‘所在年的上一年的第一天’
–上一年年末,计算给定日期所在年的上一年的最后一天
SELECT DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),-1) AS ‘所在年的上一年的最后一天’
–下一年年初,计算给定日期所在年的下一年的第一天
SELECT DATEADD(YEAR,1+DATEDIFF(YEAR,0,@Date),0) AS ‘所在年的下一年的第一天’
–下一年年末,计算给定日期所在年的下一年的最后一天
SELECT DATEADD(YEAR,1+DATEDIFF(YEAR,-1,@Date),-1) AS ‘所在年的下一年的最后一天’
GO

–季度计算
DECLARE @Date  DATETIME
SET @Date=GETDATE()
–季度初,计算给定日期所在季度的第一天
SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date),0) AS ‘当前季度的第一天’
–季度末,计算给定日期所在季度的最后一天
SELECT DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date),-1) AS ‘当前季度的最后一天’
–上个季度初
SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date)-1,0) AS ‘当前季度的上个季度初’
–上个季度末
SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date),-1) AS ‘当前季度的上个季度末’
–下个季度初
SELECT DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date),0) AS ‘当前季度的下个季度初’
–下个季度末
SELECT DATEADD(QUARTER,2+DATEDIFF(QUARTER,0,@Date),-1) AS ‘当前季度的下个季度末’
GO

–计算给定日期所在月的天数
DECLARE @Date DATETIME;
SET @Date = GETDATE()
–本月度第一天与下月度第一天所差的天数
SELECT DATEDIFF(DAY,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0),DATEADD(MONTH,1+DATEDIFF(MONTH,0,@Date),0))
–借助变量简化
SELECT @Date = DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0) –本月度第一天
SELECT DATEDIFF(DAY,@Date,DATEADD(MONTH,1,@Date))
–另一种思路:给定月最后一天的日期,记为本月天数
SELECT DAY(DATEADD(MONTH,DATEDIFF(MONTH,-1,@Date),-1))
GO

–计算给定日期所在季度的天数
DECLARE @Date DATETIME;
SET @Date = GETDATE()
–本季度第一天与下季度第一天所差的天数
SELECT DATEDIFF(DAY,DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date),0),DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date),0))
–借助变量简化
SELECT @Date = DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date),0) –本季度第一天
SELECT DATEDIFF(DAY,@Date,DATEADD(QUARTER,1,@Date))
GO

–计算给定日期所在年度的天数
DECLARE @Date DATETIME;
SET @Date = GETDATE()
–本年度第一天与下年度第一天所差的天数
SELECT DATEDIFF(DAY,DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),0),DATEADD(YEAR,1+DATEDIFF(YEAR,0,@Date),0))
–借助变量简化
SELECT @Date = DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),0) –本年度第一天
SELECT DATEDIFF(DAY,@Date,DATEADD(YEAR,1,@Date))
GO

–判断给定日期所在年是否闰年
–根据全年总天数判断
DECLARE @Date DATETIME;
SET @Date = GETDATE()
SELECT CASE DATEDIFF(DAY,DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),0),DATEADD(YEAR,1+DATEDIFF(YEAR,0,@Date),0))
  WHEN 365 THEN ‘平年’ ELSE ‘闰年’ END
–根据二月天数判断
–给日期的上一年最后一天加2个月,即为当年2月最后一天
SELECT CASE DAY(DATEADD(MONTH,2,DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),-1))) WHEN 28 THEN ‘平年’ ELSE ‘闰年’ END
GO

–计算给定日期是当年的第几天
DECLARE @Date DATETIME;
SET @Date = GETDATE()
SELECT DATEPART(DAYOFYEAR,@Date) [DayOfYear];
SELECT DATENAME(DAYOFYEAR,@Date)  [DayOfYear];
–另一种思路:当前日期与上年最后一天差的天数
SELECT DATEDIFF(DAY,DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),-1),@Date)[DayOfYear]
GO

–计算给定日期是当年的第几周
DECLARE @Date DATETIME;
SET @Date = GETDATE()
SELECT DATEPART(WEEK,@Date) [WeekOfYear]; –返回int型
SELECT DATENAME(WEEK,@Date) [WeekOfYear]; –返回varchar型
GO

–计算给定日期是当年的第几月
DECLARE @Date DATETIME;
SET @Date = GETDATE()
SELECT DATEPART(MONTH,@Date) [MonthOfYear]; –返回int型
SELECT DATENAME(MONTH,@Date) [MonthOfYear]; –返回varchar型
SELECT MONTH(@Date) [MonthOfYear];–返回int型
GO

–计算给定日期是当年的第几季度
DECLARE @Date DATETIME;
SET @Date = GETDATE()
SELECT DATEPART(QUARTER,@Date) [QuarterOfYear]; –返回int型
SELECT DATENAME(QUARTER,@Date) [QuarterOfYear]; –返回varchar型
GO

–计算给定日期是当月的第几周
DECLARE @Date DATETIME;
SET @Date = GETDATE()
–思路,给定日期是当年的第几周-给定日期所在月第一天是当年的第几周
SELECT DATEPART(WEEK,@Date)-DATEPART(WEEK,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0))+1 [WeekOfMonth]
SELECT DATEPART(WEEK,@Date)-DATEPART(WEEK,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date))+1 [WeekOfMonth]
GO

–计算给定日期所在月的第一个星期一是哪天
DECLARE @Date DATETIME;
SET @Date = GETDATE()
–思路,1900-01-01(星期一)加上(给定日志所在月的月6号与1900-01-01差的周数)个周
–为什么不选7号?如果是7号,那么7好恰好是星期日的话,第一个周一就会算到8号。
–为什么不选5号?如果5号是星期六,那么周一就跑到上月了。小于5号与这个道理一样。
SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,6-DATEPART(DAY,@Date),@Date)),0) ‘所在月的第一个星期一’
SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,6-DATEPART(DAY,@Date),@Date)),7) ‘所在月的第二个星期一’
SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,6-DATEPART(DAY,@Date),@Date)),1) ‘所在月的第一个星期二’
SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,6-DATEPART(DAY,@Date),@Date)),8) ‘所在月的第二个星期二’
GO