分类 默认 下的文章
BASE64 编码介绍与实现
- 作者: thebadzhang
- 时间:
- 分类: 默认
- 评论
Base64
[TOC]
Base64 是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看 [RFC2045][RFC2045]、[RFC2046][RFC2046]、[RFC2047][RFC2047]、[RFC2048][RFC2048]、[RFC2049][RFC2049],上面有 MIME 的详细规范。
Base64 编码是从二进制到字符的过程,可用于在 HTTP 环境下传递较长的标识信息。采用 Base64 编码具有不可读性,需要解码后才能阅读。
Base64 由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了 Base64 的各种“变种”。为统一和规范化 Base64 的输出, Base62x 被视为无符号化的改进版本。
简介
标准的 Base64 并不适合直接放在URL里传输,因为 URL 编码器会把标准 Base64 中的/和+字符变为形如%XX的形式,而这些%号在存入数据库时还需要再进行转换,因为 ANSI SQL 中已将%号用作通配符。
为解决此问题,可采用一种用于 URL 的改进 Base64 编码,它在末尾填充=号,并将标准 Base64 中的+和/分别改成了-和_,这样就免去了在 URL 编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
另有一种用于正则表达式的改进 Base64 变种,它将+和/改成了!和-,因为+,*以及前面在 IRCu 中用到的[和]在正则表达式中都可能具有特殊含义。
此外还有一些变种,它们将+/改为_-或._(用作编程语言中的标识符名称)或.-(用于 XML 中的 Nmtoken )甚至_:(用于 XML 中的 Name )。
Base64 要求把每三个 8Bit 的字节转换为四个 6Bit 的字节(3*8 = 4*6 = 24),然后把 6Bit 再添两位高位 0,组成四个 8Bit 的字节,也就是说,转换后的字符串理论上将要比原来的长 1/3。
应用
Mozilla Thunderbird和Evolution用Base64来保密电子邮件密码
Base64 也会经常用作一个简单的“加密”来保护某些数据,而真正的加密通常都比较繁琐。
垃圾讯息传播者用Base64来避过反垃圾邮件工具,因为那些工具通常都不会翻译Base64的讯息。
在LDIF档案,Base64用作编码字串。
规则
关于这个编码的规则:
-
把 3 个字节变成 4 个字节。
-
每 76 个字符加一个换行符。
- 最后的结束符也要处理。
例子1
转换前 11111111,11111111,11111111 (二进制)
转换后 00111111,00111111,00111111,00111111 (二进制)
上面的三个字节是原文,下面的四个字节是转换后的 Base64 编码,其前两位均为 0。
转换后,我们用一个码表来得到我们想要的字符串(也就是最终的 Base64 编码),这个表是这样的:(摘自 [RFC2045][RFC2045] )
转换表
Table 1: The Base64 Alphabet
索引|对应字符|索引|对应字符|索引|对应字符|索引|对应字符
|-:|:-|-:|:-|-:|:-|-:|:-|
|0|A|17|R|34|i|51|z|
|1|B|18|S|35|j|52|0|
|2|C|19|T|36|k|53|1|
|3|D|20|U|37|l|54|2|
|4|E|21|V|38|m|55|3|
|5|F|22|W|39|n|56|4|
|6|G|23|X|40|o|57|5|
|7|H|24|Y|41|p|58|6|
|8|I|25|Z|42|q|59|7|
|9|J|26|a|43|r|60|8|
|10|K|27|b|44|s|61|9|
|11|L|28|c|45|t|62|+|
|12|M|29|d|46|u|63|/|
|13|N|30|e|47|v|
|14|O|31|f|48|w|
|15|P|32|g|49|x|
|16|Q|33|h|50|y|
例子2
转换前 10101101,10111010,01110110
转换后 00101011,00011011,00101001,00110110
十进制 43 27 41 54
对应码表中的值 r b p 2
所以上面的 24 位编码,编码后的 Base64 值为 rbp2
解码同理,把 rbq2 的二进制位连接上再重组得到三个 8 位值,得出原码。
(解码只是编码的逆过程,有关 MIME 的 RFC 还有很多,如果需要详细情况请自行查找。)
- 第一个字节,根据源字节的第一个字节处理。
规则:源第一字节右移两位,去掉低 2 位,高 2 位补零。
既:00 + 高6位
- 第二个字节,根据源字节的第一个字节和第二个字节联合处理。
规则如下,第一个字节高6位去掉然后左移四位,第二个字节右移四位
即:源第一字节低2位 + 源第2字节高4位
- 第三个字节,根据源字节的第二个字节和第三个字节联合处理,
规则第二个字节去掉高4位并左移两位(得高6位),第三个字节右移6位并去掉高6位(得低2位),相加即可
- 第四个字节,规则,源第三字节去掉高2位即可
//用更接近于编程的思维来说,编码的过程是这样的:
// 第一个字符通过右移2位获得第一个目标字符的Base64表位置,根据这个数值取到表上相应的字符,就是第一个目标字符。
// 然后将第一个字符与0x03(00000011)进行与(&)操作并左移4位,接着第二个字符右移4位与前者相或(|),即获得第二个目标字符。
// 再将第二个字符与0x0f(00001111)进行与(&)操作并左移2位,接着第三个字符右移6位与前者相或(|),获得第三个目标字符。
// 最后将第三个字符与0x3f(00111111)进行与(&)操作即获得第四个目标字符。
// 在以上的每一个步骤之后,再把结果与 0x3F 进行 AND 位操作,就可以得到编码后的字符了。
原文的字节数量应该是 3 的倍数,如果这个条件不能满足的话,具体的解决办法是这样的:原文剩余的字节根据编码规则继续单独转 (1变2,2变3;不够的位数用0补全),再用=号补满 4 个字节。这就是为什么有些 Base64 编码会以一个或两个等号结束的原因,但等号最多只有两个。因为一个原字节至少会变成两个目标字节,所以余数任何情况下都只可能是 0,1,2 这三个数中的一个。如果余数是 0 的话,就表示原文字节数正好是 3 的倍数(最理想的情况)。如果是 1 的话,转成 2 个 Base64 编码字符,为了让 Base64 编码是 4 的倍数,就要补 2 个等号;同理,如果是 2 的话,就要补 1 个等号。
原理
转码过程例子:
3*8=4*6
内存 1 个字节占 8 位
转前: s 1 3
先转成ascii:对应 115 49 51
2 进制: 01110011 00110001 00110011
6 个一组(4 组) 011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后计算机一个字节占 8 位,不够就自动补两个高位0了
所以有了高位补 0
科学计算器输入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查下对照表 c z E z
[RFC2045]: https://tools.ietf.org/html/rfc2045 "Multipurpose Internet Mail Extensions
(MIME) Part One:
Format of Internet Message Bodies"
[RFC2046]: https://tools.ietf.org/html/rfc2046 "Multipurpose Internet Mail Extensions
(MIME) Part Two:
Media Types"
[RFC2047]: https://tools.ietf.org/html/rfc2047 "Multipurpose Internet Mail Extensions
(MIME) Part Three:
Message Header Extensions for Non-ASCII Text"
[RFC2048]: https://tools.ietf.org/html/rfc2048 "Multipurpose Internet Mail Extensions
(MIME) Part Four:
Registration Procedures"
[RFC2049]: https://tools.ietf.org/html/rfc2049 "Multipurpose Internet Mail Extensions
(MIME) Part Five:
Conformance Criteria and Examples"
《史记·货殖列传》天下熙熙,皆为利来;天下攘攘,皆为利往。
- 作者: thebadzhang
- 时间:
- 分类: 默认
- 评论
老子曰:“至治之极,邻国相望,鸡狗之声相闻,民各甘其食,美其服,安其俗,乐其业,至老死不相往来。”必用此为务,輓近世涂民耳目,则几无行矣。
太史公曰:夫神农以前,吾不知已。至若诗书所述虞夏以来,耳目欲极声色之好,口欲穷刍豢之味,身安逸乐,而心夸矜埶能之荣。使俗之渐民久矣,虽户说以眇论,终不能化。故善者因之,其次利道之,其次教诲之,其次整齐之,最下者与之争。
夫山西饶材、竹、穀、纑、旄、玉石;山东多鱼、盐、漆、丝、声色;江南出棻、梓、姜、桂、金、锡、连、丹沙、犀、玳瑁、珠玑、齿革;龙门、碣石北多马、牛、羊、旃裘、筋角;铜、铁则千里往往山出釭置:此其大较也。皆中国人民所喜好,谣俗被服饮食奉生送死之具也。故待农而食之,虞而出之,工而成之,商而通之。此宁有政教发徵期会哉?人各任其能,竭其力,以得所欲。故物贱之徵贵,贵之徵贱,各劝其业,乐其事,若水之趋下,日夜无休时,不召而自来,不求而民出之。岂非道之所符,而自然之验邪?
周书曰:“农不出则乏其食,工不出则乏其事,商不出则三宝绝,虞不出则财匮少。”财匮少而山泽不辟矣。此四者,民所衣食之原也。原大则饶,原小则鲜。上则富国,下则富家。贫富之道,莫之夺予,而巧者有馀,拙者不足。故太公望封於营丘,地潟卤,人民寡,於是太公劝其女功,极技巧,通鱼盐,则人物归之,繦至而辐凑。故齐冠带衣履天下,海岱之间敛袂而往朝焉。其後齐中衰,管子修之,设轻重九府,则桓公以霸,九合诸侯,一匡天下;而管氏亦有三归,位在陪臣,富於列国之君。是以齐富彊至於威、宣也。
故曰:“仓廪实而知礼节,衣食足而知荣辱。”礼生於有而废於无。故君子富,好行其德;小人富,以適其力。渊深而鱼生之,山深而兽往之,人富而仁义附焉。富者得埶益彰,失埶则客无所之,以而不乐。夷狄益甚。谚曰:“千金之子,不死於市。”此非空言也。故曰:“天下熙熙,皆为利来;天下攘攘,皆为利往。”夫千乘之王,万家之侯,百室之君,尚犹患贫,而况匹夫编户之民乎!
昔者越王勾践困於会稽之上,乃用范蠡、计然。计然曰:“知斗则修备,时用则知物,二者形则万货之情可得而观已。故岁在金,穰;水,毁;木,饥;火,旱。旱则资舟,水则资车,物之理也。六岁穰,六岁旱,十二岁一大饥。夫粜,二十病农,九十病末。末病则财不出,农病则草不辟矣。上不过八十,下不减三十,则农末俱利,平粜齐物,关市不乏,治国之道也。积著之理,务完物,无息币。以物相贸易,腐败而食之货勿留,无敢居贵。论其有馀不足,则知贵贱。贵上极则反贱,贱下极则反贵。贵出如粪土,贱取如珠玉。财币欲其行如流水。”修之十年,国富,厚赂战士,士赴矢石,如渴得饮,遂报彊吴,观兵中国,称号“五霸”。
范蠡既雪会稽之耻,乃喟然而叹曰:“计然之策七,越用其五而得意。既已施於国,吾欲用之家。”乃乘扁舟浮於江湖,变名易姓,適齐为鸱夷子皮,之陶为硃公。硃公以为陶天下之中,诸侯四通,货物所交易也。乃治产积居。与时逐而不责於人。故善治生者,能择人而任时。十九年之中三致千金,再分散与贫交疏昆弟。此所谓富好行其德者也。後年衰老而听子孙,子孙脩业而息之,遂至巨万。故言富者皆称陶硃公。
子赣既学於仲尼,退而仕於卫,废著鬻财於曹、鲁之间,七十子之徒,赐最为饶益。原宪不厌糟糠,匿於穷巷。子贡结驷连骑,束帛之币以聘享诸侯,所至,国君无不分庭与之抗礼。夫使孔子名布扬於天下者,子贡先後之也。此所谓得埶而益彰者乎?
白圭,周人也。当魏文侯时,李克务尽地力,而白圭乐观时变,故人弃我取,人取我与。夫岁孰取穀,予之丝漆;茧出取帛絮,予之食。太阴在卯,穰;明岁衰恶。至午,旱;明岁美。至酉,穰;明岁衰恶。至子,大旱;明岁美,有水。至卯,积著率岁倍。欲长钱,取下穀;长石斗,取上种。能薄饮食,忍嗜欲,节衣服,与用事僮仆同苦乐,趋时若猛兽挚鸟之发。故曰:“吾治生产,犹伊尹、吕尚之谋,孙吴用兵,商鞅行法是也。是故其智不足与权变,勇不足以决断,仁不能以取予,彊不能有所守,虽欲学吾术,终不告之矣。”盖天下言治生祖白圭。白圭其有所试矣,能试有所长,非苟而已也。
猗顿用盬盐起。而邯郸郭纵以铁冶成业,与王者埒富。
乌氏倮畜牧,及众,斥卖,求奇缯物,间献遗戎王。戎王什倍其偿,与之畜,畜至用谷量马牛。秦始皇帝令倮比封君,以时与列臣朝请。而巴寡妇清,其先得丹穴,而擅其利数世,家亦不訾。清,寡妇也,能守其业,用财自卫,不见侵犯。秦皇帝以为贞妇而客之,为筑女怀清台。夫倮鄙人牧长,清穷乡寡妇,礼抗万乘,名显天下,岂非以富邪?
汉兴,海内为一,开关梁,弛山泽之禁,是以富商大贾周流天下,交易之物莫不通,得其所欲,而徙豪杰诸侯彊族於京师。
关中自汧、雍以东至河、华,膏壤沃野千里,自虞夏之贡以为上田,而公刘適邠,大王、王季在岐,文王作丰,武王治镐,故其民犹有先王之遗风,好稼穑,殖五穀,地重,重为邪。及秦文、、缪居雍,隙陇蜀之货物而多贾。献公徙栎邑,栎邑北卻戎翟,东通三晋,亦多大贾。昭治咸阳,因以汉都,长安诸陵,四方辐凑并至而会,地小人众,故其民益玩巧而事末也。南则巴蜀。巴蜀亦沃野,地饶卮、姜、丹沙、石、铜、铁、竹、木之器。南御滇僰,僰僮。西近邛笮,笮马、旄牛。然四塞,栈道千里,无所不通,唯襃斜绾毂其口,以所多易所鲜。天水、陇西、北地、上郡与关中同俗,然西有羌中之利,北有戎翟之畜,畜牧为天下饶。然地亦穷险,唯京师要其道。故关中之地,於天下三分之一,而人众不过什三;然量其富,什居其六。
昔唐人都河东,殷人都河内,周人都河南。夫三河在天下之中,若鼎足,王者所更居也,建国各数百千岁,土地小狭,民人众,都国诸侯所聚会,故其俗纤俭习事。杨、平阳陈西贾秦、翟,北贾种、代。种、代,石北也,地边胡,数被寇。人民矜懻忮,好气,任侠为奸,不事农商。然迫近北夷,师旅亟往,中国委输时有奇羡。其民羯羠不均,自全晋之时固已患其僄悍,而武灵王益厉之,其谣俗犹有赵之风也。故杨、平阳陈掾其间,得所欲。温、轵西贾上党,北贾赵、中山。中山地薄人众,犹有沙丘纣淫地馀民,民俗懁急,仰机利而食。丈夫相聚游戏,悲歌慷慨,起则相随椎剽,休则掘冢作巧奸冶,多美物,为倡优。女子则鼓鸣瑟,跕屣,游媚贵富,入後宫,遍诸侯。
然邯郸亦漳、河之间一都会也。北通燕、涿,南有郑、卫。郑、卫俗与赵相类,然近梁、鲁,微重而矜节。濮上之邑徙野王,野王好气任侠,卫之风也。
夫燕亦勃、碣之间一都会也。南通齐、赵,东北边胡。上谷至辽东,地踔远,人民希,数被寇,大与赵、代俗相类,而民雕捍少虑,有鱼盐枣栗之饶。北邻乌桓、夫馀,东绾秽貉、朝鲜、真番之利。
洛阳东贾齐、鲁,南贾梁、楚。故泰山之阳则鲁,其阴则齐。
齐带山海,膏壤千里,宜桑麻,人民多文采布帛鱼盐。临菑亦海岱之间一都会也。其俗宽缓阔达,而足智,好议论,地重,难动摇,怯於众斗,勇於持刺,故多劫人者,大国之风也。其中具五民。
而邹、鲁滨洙、泗,犹有周公遗风,俗好儒,备於礼,故其民龊龊。颇有桑麻之业,无林泽之饶。地小人众,俭啬,畏罪远邪。及其衰,好贾趋利,甚於周人。
夫自鸿沟以东,芒、砀以北,属巨野,此梁、宋也。陶、睢阳亦一都会也。昔尧作成阳,舜渔於雷泽,汤止于亳。其俗犹有先王遗风,重厚多君子,好稼穑,虽无山川之饶,能恶衣食,致其蓄藏。
越、楚则有三俗。夫自淮北沛、陈、汝南、南郡,此西楚也。其俗剽轻,易发怒,地薄,寡於积聚。江陵故郢都,西通巫、巴,东有云梦之饶。陈在楚夏之交,通鱼盐之货,其民多贾。徐、僮、取虑,则清刻,矜己诺。
彭城以东,东海、吴、广陵,此东楚也。其俗类徐、僮。朐、缯以北,俗则齐。浙江南则越。夫吴自阖庐、春申、王濞三人招致天下之喜游子弟,东有海盐之饶,章山之铜,三江、五湖之利,亦江东一都会也。
衡山、九江、江南、豫章、长沙,是南楚也,其俗大类西楚。郢之後徙寿春,亦一都会也。而合肥受南北潮,皮革、鲍、木输会也。与闽中、干越杂俗,故南楚好辞,巧说少信。江南卑湿,丈夫早夭。多竹木。豫章出黄金,长沙出连、锡,然堇堇物之所有,取之不足以更费。九疑、苍梧以南至儋耳者,与江南大同俗,而杨越多焉。番禺亦其一都会也,珠玑、犀、玳瑁、果、布之凑。
颍川、南阳,夏人之居也。夏人政尚忠朴,犹有先王之遗风。颍川敦愿。秦末世,迁不轨之民於南阳。南阳西通武关、郧关,东南受汉、江、淮。宛亦一都会也。俗杂好事,业多贾。其任侠,交通颍川,故至今谓之“夏人”。
夫天下物所鲜所多,人民谣俗,山东食海盐,山西食盐卤,领南、沙北固往往出盐,大体如此矣。
总之,楚越之地,地广人希,饭稻羹鱼,或火耕而水耨,果隋蠃蛤,不待贾而足,地埶饶食,无饥馑之患,以故呰窳偷生,无积聚而多贫。是故江淮以南,无冻饿之人,亦无千金之家。沂、泗水以北,宜五穀桑麻六畜,地小人众,数被水旱之害,民好畜藏,故秦、夏、梁、鲁好农而重民。三河、宛、陈亦然,加以商贾。齐、赵设智巧,仰机利。燕、代田畜而事蚕。
由此观之,贤人深谋於廊庙,论议朝廷,守信死节隐居岩穴之士设为名高者安归乎?归於富厚也。是以廉吏久,久更富,廉贾归富。富者,人之情性,所不学而俱欲者也。故壮士在军,攻城先登,陷阵卻敌,斩将搴旗,前蒙矢石,不避汤火之难者,为重赏使也。其在闾巷少年,攻剽椎埋,劫人作奸,掘冢铸币,任侠并兼,借交报仇,篡逐幽隐,不避法禁,走死地如骛者,其实皆为财用耳。今夫赵女郑姬,设形容,揳鸣琴,揄长袂,蹑利屣,目挑心招,出不远千里,不择老少者,奔富厚也。游闲公子,饰冠剑,连车骑,亦为富贵容也。弋射渔猎,犯晨夜,冒霜雪,驰阬谷,不避猛兽之害,为得味也。博戏驰逐,斗鸡走狗,作色相矜,必争胜者,重失负也。医方诸食技术之人,焦神极能,为重糈也。吏士舞文弄法,刻章伪书,不避刀锯之诛者,没於赂遗也。农工商贾畜长,固求富益货也。此有知尽能索耳,终不馀力而让财矣。
谚曰:“百里不贩樵,千里不贩籴。”居之一岁,种之以穀;十岁,树之以木;百岁,来之以德。德者,人物之谓也。今有无秩禄之奉,爵邑之入,而乐与之比者。命曰“素封”。封者食租税,岁率户二百。千户之君则二十万,朝觐聘享出其中。庶民农工商贾,率亦岁万息二千,百万之家则二十万,而更徭租赋出其中。衣食之欲,恣所好美矣。故曰陆地牧马二百蹄,牛蹄角千,千足羊,泽中千足彘,水居千石鱼陂,山居千章之材。安邑千树枣;燕、秦千树栗;蜀、汉、江陵千树橘;淮北、常山已南,河济之间千树萩;陈、夏千亩漆;齐、鲁千亩桑麻;渭川千亩竹;及名国万家之城,带郭千亩亩锺之田,若千亩卮茜,千畦姜韭:此其人皆与千户侯等。然是富给之资也,不窥市井,不行异邑,坐而待收,身有处士之义而取给焉。若至家贫亲老,妻子软弱,岁时无以祭祀进醵,饮食被服不足以自通,如此不惭耻,则无所比矣。是以无财作力,少有斗智,既饶争时,此其大经也。今治生不待危身取给,则贤人勉焉。是故本富为上,末富次之,奸富最下。无岩处奇士之行,而长贫贱,好语仁义,亦足羞也。
凡编户之民,富相什则卑下之,伯则畏惮之,千则役,万则仆,物之理也。夫用贫求富,农不如工,工不如商,刺绣文不如倚市门,此言末业,贫者之资也。通邑大都,酤一岁千酿,醯酱千瓨,浆千甔,屠牛羊彘千皮,贩穀粜千锺,薪千车,船长千丈,木千章,竹竿万个,其轺车百乘,牛车千两,木器魨者千枚,铜器千钧,素木铁器若卮茜千石,马蹄躈千,牛千足,羊彘千双,僮手指千,筋角丹沙千斤,其帛絮细布千钧,文采千匹,榻布皮革千石,漆千斗,糵麹盐豉千荅,鮐{此鱼}千斤,鲰千石,鲍千钧,枣栗千石者三之,狐龂裘千皮,羔羊裘千石,旃席千具,佗果菜千锺,子贷金钱千贯,节駔会,贪贾三之,廉贾五之,此亦比千乘之家,其大率也。佗杂业不中什二,则非吾财也。
请略道当世千里之中,贤人所以富者,令後世得以观择焉。
蜀卓氏之先,赵人也,用铁冶富。秦破赵,迁卓氏。卓氏见虏略,独夫妻推辇,行诣迁处。诸迁虏少有馀财,争与吏,求近处,处葭萌。唯卓氏曰:“此地狭薄。吾闻汶山之下,沃野,下有蹲鸱,至死不饥。民工於市,易贾。”乃求远迁。致之临邛,大喜,即铁山鼓铸,运筹策,倾滇蜀之民,富至僮千人。田池射猎之乐,拟於人君。
程郑,山东迁虏也,亦冶铸,贾椎髻之民,富埒卓氏,俱居临邛。
宛孔氏之先,梁人也,用铁冶为业。秦伐魏,迁孔氏南阳。大鼓铸,规陂池,连车骑,游诸侯,因通商贾之利,有游闲公子之赐与名。然其赢得过当,愈於纤啬,家致富数千金,故南阳行贾尽法孔氏之雍容。
鲁人俗俭啬,而曹邴氏尤甚,以铁冶起,富至巨万。然家自父兄子孙约,俯有拾,仰有取,贳贷行贾遍郡国。邹、鲁以其故多去文学而趋利者,以曹邴氏也。
齐俗贱奴虏,而刀间独爱贵之。桀黠奴,人之所患也,唯刀间收取,使之逐渔盐商贾之利,或连车骑,交守相,然愈益任之。终得其力,起富数千万。故曰“宁爵毋刀”,言其能使豪奴自饶而尽其力。
周人既纤,而师史尤甚,转毂以百数,贾郡国,无所不至。洛阳街居在齐秦楚赵之中,贫人学事富家,相矜以久贾,数过邑不入门,设任此等,故师史能致七千万。
宣曲任氏之先,为督道仓吏。秦之败也,豪杰皆争取金玉,而任氏独窖仓粟。楚汉相距荥阳也,民不得耕种,米石至万,而豪杰金玉尽归任氏,任氏以此起富。富人争奢侈,而任氏折节为俭,力田畜。田畜人争取贱贾,任氏独取贵善。富者数世。然任公家约,非田畜所出弗衣食,公事不毕则身不得饮酒食肉。以此为闾里率,故富而主上重之。
塞之斥也,唯桥姚已致马千匹,牛倍之,羊万头,粟以万锺计。吴楚七国兵起时,长安中列侯封君行从军旅,赍贷子钱,子钱家以为侯邑国在关东,关东成败未决,莫肯与。唯无盐氏出捐千金贷,其息什之。三月,吴楚平,一岁之中,则无盐氏之息什倍,用此富埒关中。
关中富商大贾,大抵尽诸田,田啬、田兰。韦家栗氏,安陵、杜杜氏,亦巨万。
此其章章尤异者也。皆非有爵邑奉禄弄法犯奸而富,尽椎埋去就,与时俯仰,获其赢利,以末致财,用本守之,以武一切,用文持之,变化有概,故足术也。若至力农畜,工虞商贾,为权利以成富,大者倾郡,中者倾县,下者倾乡里者,不可胜数。
夫纤啬筋力,治生之正道也,而富者必用奇胜。田农,掘业,而秦扬以盖一州。掘冢,奸事也,而田叔以起。博戏,恶业也,而桓发用富。行贾,丈夫贱行也,而雍乐成以饶。贩脂,辱处也,而雍伯千金。卖浆,小业也,而张氏千万。洒削,薄技也,而郅氏鼎食。胃脯,简微耳,浊氏连骑。马医,浅方,张里击锺。此皆诚壹之所致。
由是观之,富无经业,则货无常主,能者辐凑,不肖者瓦解。千金之家比一都之君,巨万者乃与王者同乐。岂所谓“素封”者邪?非也?
货殖之利,工商是营。废居善积,倚巿邪赢。白圭富国,计然强兵。倮参朝请,女筑怀清。素封千户,卓郑齐名。
微积分初步——使用 Lua 来表示微积分
- 作者: thebadzhang
- 时间:
- 分类: 默认
- 评论
微积分初步
函数、导数与微分
我们首先学习导数和微积分等概念和有关的基本运算方法
变量、常量和函数
会变化的量叫变量,不会变化的量叫做常量
pi<const> = 3.14159265357
x = 3
自变量和因变量
现有两个互相联系的两个变量$x$和$y$,如果当$x$在其变域$\mathscr{D}$内任意取一数值时,都有确定的值与之对应,则称$y$时$x$的函数,$x$叫做自变量,函数$y$又称作因变量,写作:
$$y=f(x)$$
变域$\mathscr{D}$为自变量的变化范围,称作函数$f(x)$的定义域,而所有的数值则构成$y$的值域$\mathscr{R}$例如,
若$y$为$z$的函数,$y=f(x)$;而$z$又是变量$x$的函数,即$z=g(x)$,则称$y$为$x$的复合函数,记作
$$y=\phi(x)=f[g(x)]$$
导数
daoshu = function (fx, x, dx)
assert (fx == "function", "第一个[参数]^(Parameter)必须是一个函数")
assert (x, "请输入你想要计算的那个点")
if not dx then dx = 1E-12 end
return (fx(x+dx)-fx(x))/dx
end
如此这般操作,我们就实现了一个拥有强鲁棒性的导数计算工具,但是由于计算机底层运算本身所具有的不精确性,而且我们也没有使用较为复杂的方法进行计算,可能会导致结果有所偏差,但是误差应该会在1%以下
函数的极值点和极值
微分
不定积分
原函数
不定积分
不定积分的运算法则
定积分
定积分的概念
定积分的主要性质
牛顿-莱布尼茨公式
C/C++ 入门前提须知不完全指北
- 作者: thebadzhang
- 时间:
- 分类: 默认
- 评论
C/C++ 入门前提须知不完全指北
本文档用于指导学校不大可能会教,但是又必知的要点(知道有,能简单用就好了,深入的学习还请在深入了解了 c/c++ 之后再做详细的研究学习
也有可能是在后面会教,或是在学习的过程中就学会了……
C 版本与 C++ 版本
K&B C
ANSI C
ISO C
c89
c99
c11
c17
C++98
C++03
C++11
C++14
C++17
C++20
C++23
gcc
mingw
mingw-w64
tdm-gcc
clang-llvm
msvc
末流
borderland++
intel++
大部分的学校所使用的 IDE 无非逃不开 devcpp 5.11 code::blocks VC2010 VC6,这么几种选择。
VC6 属于历史惯性,虽然已经是 上个世纪 98 年的产物,但是完全够教材用,存在的很多局限性,大多数大学生可能也没有太多的感觉。
VC2010 实际上指的是 VC++ 2010 Express 的这种奇奇怪怪的版本,免费,而且轻量,支持的标准也比 VC6 更新,但是也不支持 c++11,但是这个环境已经是目前国家计算机二级等级考试的标准环境,所以,使用 VC6 是真的**。
devcpp 用更老版本的虽然少见,但是确实还是存在的,主流还是 devcpp 5.11 比如我现在就读的这个学校。实际上devcpp 在相当一定的程度上还可以勉强跟上时代的潮流。
当然,通过更换编译器也可以达到这个效果,不过,和老师的环境不太一样,就没有什么需要考虑的了。devcpp 5.11 支持 c++11,不过需要自己手动开启设置 启用 c++11 或者启动编译器选项 -std=c++11
这里理应需要一张图通过直接勾选启用c++11,但是还没有配置对应环境
![]()
这里应该有一张如何通过编译器选项设置c++11的图片,也没有环境
![]()
code::blocks 可以自动根据系统中的编译器自动配置环境,但是由于官网有一个默认的带有 MinGW 的版本,所以以下的所有内容,也以此为“标准”
实际上 devcpp 和 code::blocks 所使用的编译器都是基于同一个编译器所产生的不同分支,也就是说,同一个妈生的,从使用上,除了 IDE 本身的差别,不会有太多的问题
报错
第一步,当然也是最重要的一步,前面那个只是前言,不看也罢,教不了什么东西
如何看自己的报错
如果你在使用 VS 之流的 IDE,你可以看到它的C++ 报错是有中文的,这个时候可以很方便地看到自己的错误,具体内容是什么意思,但是熟练了,其实看什么都差不多。
一个报错通常会标识一个错误的位置,引发了什么样的错误
部分 ide 提供了双击跳转到错误代码的功能,这个很实用
通常报错总是会由前面的某一个错误,引发一个连锁反应
(关于 C++ 使用到了模板的话,一个报错可能就是几百上千行,此时中间一堆都不用管,直接看到最前面的错误原因就行了)
当程序中存在游离的字符,中文或者是空白字符,通常来说总是后面的问题,因为看到了中文的字符谁不知道它有问题呢,总是一些看不到的符号引发着奇奇怪怪的错误。
又比如函数参数啊,返回值啊等等等等
undefined reference: 未定义的引用,通常是因为include了某个头文件,但是却没有添加对应的源文件或者是库文件,导致函数定义不存在。
不对应的括号,花括号
错误的名称
逗号,分号,中文标点符号
警告
没事,既然只是警告,没有遇到奇葩的问题,就不用管了,
通常是一些什么变量没有使用啊,存在隐式转换什么的,特别奇怪
理解编译的过程
#include <stdio.h>
int main (int argc, char **argv) {
printf ("Hello World!");
return 0;
}
这是一个基本的 c 程序,包含了一个宏用于引用别的头文件
main 作为一个入口函数,在程序启动的时候调用
int 是这个函数的返回值,c 标准中没有要求 main 必须返回,或者返回什么
int argc, char**argv 是这个程序启动时输入的参数,你可能操作过类似于,在命令行使用的工具,比如 git 工具,使用 git clone xxx 可以从远端克隆一个项目,每一个参数如何分割是由终端决定的(毕竟万一不支持字符串什么的,也可能是一些问题呢)
printf ("Hello World!"); 是一个调用了标准格式化输出函数,输出字符串的语句,会在你的终端上显示出 Hello World! 这些字符。所谓终端就是你所看到的黑色的窗口,
print 打印
f format 格式化
printf 格式化输出,标准库提供的,所以又叫标准格式化输出函数
scanf sscanf sprintf... 同理
return 0; 返回值,一般 0 为正常结束,非 0 则表示程序出现了异常,在 Windows Command 下,你可以通过打印 %ERRORLEVEL% 的值显示程序返回值(这个内容不是很属于今天要教的内容
$ gcc -o mytest.exe mytest.c -Wall
我们使用如上的命令进行对代码的编译,产生如下的编译结果
$ ./mytest
Hello World!
但实际使用中,使用的更多的还是 make 来进行对项目的构建,make 配置文件通常会由 IDE 进行创建,例如上面提到的,但是 vs 的 make 文件就,比较有特色
预编译、预处理
这个部分将宏进行展开,删除注释
语法检查
检查括号啊,参数类型啊等等等等
语义检查
分析、替换、编译、优化
这部分应该去看一些关于编译原理的书,例如《编译原理》
链接
头文件,库文件,静态链接库动态链接库
标准库为什么没有要我们链接库
因为这个库在系统的内部被提供了
大多数操作系统都会内置一个 c/c++ 的动态链接库给程序链接,实现标准的功能
不同系统的 C++ 标准库在哪
libstdc++.so
什么的
配置链接
-l
-L
编译器选项
-o
-g
-s
-O2
-O3
-O4
构建一个项目
C/C++ 作为一个复杂的工程语言,当然,不是说语法上的复杂,说的是项目之间协作,调库,编译,跨平台编译,使之能够运行是非常复杂的。大家通常使用 makefile 来解决复杂的命令,但是和 .bat .sh 文件来说可能,更加方便令人懂。但是,不同的编译器可能拥有不同的 makefile 语法,然后,很多跨平台跨编译器的项目就需要为这些事情做一些特化,比如附带了一堆的 makefile ,这个通常为实际上的开发产生了相当多的麻烦,因为你需要熟练掌握相当多的 makefile 的语法。然后,cmake 横空出世,通过统一的语法配置了项目,但是 cmake 本身不是直接被编译器所使用的,而是生成了对应编译器的 makefile,然后调用对应编译器对源文件进行编译。但是我觉得 cmake 的语法还是挺操蛋的,非常的不好。有人说 ninja?但是我也觉得只是一般般,然后我现在用的是 xmake,简单的配置就可以为一个项目创建基本的构建工程