Skip to content

Commit 16475e6

Browse files
authored
Merge pull request #2 from JDubbTX/bas64
Bas64
2 parents e8770ef + 9ace5e1 commit 16475e6

6 files changed

+183
-5
lines changed

_config.yml

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ titles_from_headings:
3434
strip_title: true
3535
collections: true
3636

37+
show_excerpts: true
38+
3739
defaults:
3840
- scope:
3941
path: ""

_includes/sharelinks.html

+1-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#share-buttons > div.twitter > svg {height: 20px; margin-top: 8px;}
1515
#share-buttons > div.linkedin > svg {height: 19px; margin-top: 7px;}
1616
#share-buttons > div.pinterest > svg {height: 20px; margin-top: 9px;}
17-
#share-buttons > div.gplus > svg {height: 17px; margin-top: 9px; position: relative; left: 1px;}
1817
#share-buttons > div.mail > svg {height: 14px; margin-top: 11px;}
1918
</style>
2019

@@ -25,12 +24,10 @@
2524
<span style="color: silver;">Share on: </span><div id="share-buttons">
2625
<div class="facebook" title="Share this on Facebook" onclick="window.open('http://www.facebook.com/share.php?u={{ safeurl }}','popup','width=600,height=600'); return false;">
2726
<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1343 12v264h-157q-86 0-116 36t-30 108v189h293l-39 296h-254v759h-306v-759h-255v-296h255v-218q0-186 104-288.5t277-102.5q147 0 228 12z"/></svg></div>
28-
<div class="twitter" title="Share this on Twitter" onclick="window.open('https://twitter.com/intent/tweet?url={{ safeurl }}&text={{ safetitle }}&via={{ site.twitter_username }}','popup','width=600,height=600'); return false;">
27+
<div class="twitter" title="Share this on X (formerly Twitter)" onclick="window.open('https://twitter.com/intent/tweet?url={{ safeurl }}&text={{ safetitle }}&via={{ site.twitter_username }}','popup','width=600,height=600'); return false;">
2928
<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1684 408q-67 98-162 167 1 14 1 42 0 130-38 259.5t-115.5 248.5-184.5 210.5-258 146-323 54.5q-271 0-496-145 35 4 78 4 225 0 401-138-105-2-188-64.5t-114-159.5q33 5 61 5 43 0 85-11-112-23-185.5-111.5t-73.5-205.5v-4q68 38 146 41-66-44-105-115t-39-154q0-88 44-163 121 149 294.5 238.5t371.5 99.5q-8-38-8-74 0-134 94.5-228.5t228.5-94.5q140 0 236 102 109-21 205-78-37 115-142 178 93-10 186-50z"/></svg></div>
3029
<div class="linkedin" title="Share this on Linkedin" onclick="window.open('https://www.linkedin.com/sharing/share-offsite/?url={{ safeurl }}','popup','width=600,height=600'); return false;">
3130
<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M477 625v991h-330v-991h330zm21-306q1 73-50.5 122t-135.5 49h-2q-82 0-132-49t-50-122q0-74 51.5-122.5t134.5-48.5 133 48.5 51 122.5zm1166 729v568h-329v-530q0-105-40.5-164.5t-126.5-59.5q-63 0-105.5 34.5t-63.5 85.5q-11 30-11 81v553h-329q2-399 2-647t-1-296l-1-48h329v144h-2q20-32 41-56t56.5-52 87-43.5 114.5-15.5q171 0 275 113.5t104 332.5z"/></svg></div>
32-
<div class="gplus" title="Share this on Google Plus" onclick="window.open('https://plus.google.com/share?url={{ safeurl }}','popup','width=600,height=600'); return false;">
33-
<svg viewBox="0 0 2304 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1437 913q0 208-87 370.5t-248 254-369 91.5q-149 0-285-58t-234-156-156-234-58-285 58-285 156-234 234-156 285-58q286 0 491 192l-199 191q-117-113-292-113-123 0-227.5 62t-165.5 168.5-61 232.5 61 232.5 165.5 168.5 227.5 62q83 0 152.5-23t114.5-57.5 78.5-78.5 49-83 21.5-74h-416v-252h692q12 63 12 122zm867-122v210h-209v209h-210v-209h-209v-210h209v-209h210v209h209z"/></svg></div>
3431
<div class="mail" title="Share this through Email" onclick="window.open('mailto:?&body={{ safeurl }}&subject={{ safetitlepre }}{{ safetitle }}','popup','width=600,height=600'); return false;">
3532
<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1792 710v794q0 66-47 113t-113 47h-1472q-66 0-113-47t-47-113v-794q44 49 101 87 362 246 497 345 57 42 92.5 65.5t94.5 48 110 24.5h2q51 0 110-24.5t94.5-48 92.5-65.5q170-123 498-345 57-39 100-87zm0-294q0 79-49 151t-122 123q-376 261-468 325-10 7-42.5 30.5t-54 38-52 32.5-57.5 27-50 9h-2q-23 0-50-9t-57.5-27-52-32.5-54-38-42.5-30.5q-91-64-262-182.5t-205-142.5q-62-42-117-115.5t-55-136.5q0-78 41.5-130t118.5-52h1472q65 0 112.5 47t47.5 113z"/></svg></div>
3633
</div>

_posts/2023-05-11-RPG-CICD-Setting-up-local-development.markdown

+17-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,23 @@ VSCODE automatically prompts you to download and install it the first time you c
4141

4242
![Install GIT](/assets/images/VSCODE_Install_GIT_2.gif)
4343

44+
#### Configure Git
45+
46+
The first time you use Git, you must configure some settings. Open up a bash terminal in VSCODE and run the following 2 commands:
47+
48+
```
49+
git config --global user.name "xx xxxx"
50+
git config --global user.email "[email protected]"
51+
```
52+
![Configure GIT](/assets/images/Git_Config.gif)
53+
54+
These settings will be used to identify you on every commit you make.
55+
56+
#### Set up SSH keys in Gitlab
57+
We need to generate an SSH key pair on your local PC, then enter the public key in your gitlab profile. This allows easy, secure ability to push and pull content from your PC to Gitlab. All of the following instructions are pretty much the same if you use another SCM like Github instead of Gitlab.
58+
59+
1.
60+
4461
#### Install VSCODE extensions
4562

4663
There are a multitude of extensions available for VSCODE. They are available to install in the [Visual Studio Code Marketplace](https://marketplace.visualstudio.com/VSCode), or you can access the same marketplace from within the VSCODE in the extensions sidebar view:
@@ -67,7 +84,6 @@ There are two approaches to getting a project to sync to online source control.
6784
2. Copy the project SSH clone URL and clone it
6885

6986
5. Set your deploy IFS target directory - do this in the IFS
70-
6. Set up your
7187

7288
### Setting up your IBM i profile
7389
The first work we need to do is to set up your IBM i profile for open source development
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
---
2+
layout: post
3+
title: "Base 64 Encoding and Decoding with DB2"
4+
date: 2023-10-12
5+
---
6+
7+
## Base64 Encoding and Decoding on IBM i
8+
9+
Base64 encoding is a method for converting binary data into ASCII text. It's designed to prevent communication errors when transferring binary information.
10+
11+
The IBM i operating system provides two DB2 services that allow you to BASE64 encode and decode.
12+
13+
In this post we will discuss how to use these DB2 services, and why CCSID is an important consideration. The examples given will utilize embedded SQL in an SQLRPGLE program. We will make use of a service program exported procedure named 'print_this' that will be discussed in future post about service programs.
14+
15+
### The IBM i DB2 services for base64 encoding and decoding
16+
17+
[BASE64_ENCODE](https://www.ibm.com/docs/en/i/7.5?topic=functions-base64-encode) - returns the Base64 encoded version of a binary value.
18+
19+
[BASE64_DECODE](https://www.ibm.com/docs/en/i/7.5?topic=functions-base64-decode) - returns a character string that has been Base64 decoded
20+
21+
### Trying it out
22+
23+
First lets encode a string 'MyText' in base64 using a simple SQLRPGLE program. As mentioned above, we will make use of service program sub-procedure named 'print_this' that simply prints 2 strings passed as parameters to a spoolfile.
24+
25+
``` text
26+
**free
27+
ctl-opt actgrp(*new) bnddir('BNDUTIL');
28+
29+
// Start of Main Procedure
30+
// Declare some stand-alone fields
31+
Dcl-S PlainText VARCHAR(100) INZ('MyText');
32+
Dcl-S EncodedText VARCHAR(100);
33+
34+
/copy ./qptypesrc/printer.rpgleinc
35+
36+
// Print headings
37+
print_this('Field Name' : 'Value');
38+
print_this('---------------------' : '-----------------------------------------------------------');
39+
40+
print_this('PlainText' : %Trim(PlainText));
41+
42+
// Encode the text into a VARCHAR field
43+
Exec SQL Values QSYS2.BASE64_ENCODE(:PlainText) Into :EncodedText;
44+
print_this('EncodedText' : %trim(EncodedText));
45+
46+
return;
47+
```
48+
49+
Spoolfile Output:
50+
51+
``` text
52+
Field Name Value
53+
--------------------- --------------------------------------------------------
54+
PlainText MyText
55+
EncodedText 1Kjjhaej
56+
```
57+
58+
Now, lets check that against a base64 encoder on the web: [https://www.base64encode.org/](https://www.base64encode.org/)
59+
60+
> ![bas64encode.org screen grab](/assets/images/base64-1.png)
61+
62+
The encoded value from our RPG program doesn't match the encoded value from www.base64encode.org. The reason they don't match, is because of CCSID. CCSID, or Coded Character Set Identitifier, is what uniquely identifies the specific encoding of a code page.
63+
64+
If you read the documentation for base64_encode, it gives examples of base64 encodeing for both the system default EBCDIC code page and UTF-8 (code page 1208) CCSID. ON IBM i, the default character set is EBCDIC, with the specific code page varying by region.
65+
66+
> On IBM i, ebcdic is the default character set.
67+
68+
The code page for your machine is stored in a system value called QCCSID. When your IBM i was delivered, it came with value 65535 - which isn't a real code page. 65535 is something IBM i uses to specify all character data tagging support support is turned off. IBM recommends this value be changed. In North America, the standard ebcdic code page for IBM i is 37. For more information, read up on QCCSID [here](https://www.ibm.com/docs/en/i/7.5?topic=values-coded-character-set-identifier-qccsid-system-value).
69+
70+
With that understanding, if you want to base64 encode / decode like the rest of the world, and you probably do, you need to make a CCSID adjustments to your code:
71+
72+
``` text
73+
**free
74+
ctl-opt actgrp(*new) bnddir('BNDUTIL');
75+
76+
// Start of Main Procedure
77+
// Declare some stand-alone fields
78+
Dcl-S PlainText VARCHAR(100) INZ('MyText') CCSID(1208);
79+
Dcl-S EncodedText VARCHAR(100);
80+
81+
/copy ./qptypesrc/printer.rpgleinc
82+
83+
// Print headings
84+
print_this('Field Name' : 'Value');
85+
print_this('---------------------' : '-----------------------------------------------------------');
86+
87+
print_this('PlainText' : %Trim(PlainText));
88+
89+
// Encode the text into a VARCHAR field
90+
Exec SQL Values QSYS2.BASE64_ENCODE(:PlainText) Into :EncodedText;
91+
print_this('EncodedText' : %trim(EncodedText));
92+
93+
return;
94+
```
95+
96+
Spoolfile Output:
97+
98+
``` text
99+
Field Name Value
100+
--------------------- --------------------------------------------------------
101+
PlainText MyText
102+
EncodedText TXlUZXh0
103+
```
104+
105+
In the code above, the only modification needed was to add the CCSID keyword to the definition for `PlainText`. I used the specific value of `1208`, but could also have used `*UTF8`. IBM's documentation suggests another method, which is to CAST the CCSID inline:
106+
107+
```
108+
VALUES QSYS2.BASE64_ENCODE (CAST(EncodedText AS VARCHAR(10) CCSID 1208)) Into :EncodedText;
109+
```
110+
111+
### And Now to Decode
112+
113+
Lets add a few more lines to our example that decode the now encoded message.
114+
115+
``` text
116+
**free
117+
ctl-opt actgrp(*new) bnddir('BNDUTIL');
118+
119+
// Start of Main Procedure
120+
// Declare some stand-alone fields
121+
Dcl-S PlainText VARCHAR(100) INZ('MyText') CCSID(1208);
122+
Dcl-S EncodedText VARCHAR(100);
123+
Dcl-S DecodedTextVarBinary sqltype(VARBINARY:100);
124+
Dcl-S TranslatedTextVarChar VARCHAR(100) CCSID(1208);
125+
126+
/copy ./qptypesrc/printer.rpgleinc
127+
128+
// Print headings
129+
print_this('Field Name' : 'Value');
130+
print_this('---------------------' : '-----------------------------------------------------------');
131+
132+
print_this('PlainText' : %Trim(PlainText));
133+
134+
// Encode the text into a VARCHAR field
135+
Exec SQL Values QSYS2.BASE64_ENCODE(:PlainText) Into :EncodedText;
136+
print_this('EncodedText' : %trim(EncodedText));
137+
138+
// Decode the encoded text into an EBCDIC VarBinary field
139+
Exec SQL Values QSYS2.BASE64_DECODE(:EncodedText) Into :DecodedTextVarBinary;
140+
print_this('DecodedTextVarBinary' : %trim(DecodedTextVarBinary));
141+
142+
// Translate binary data in EBCDIC to UTF-8
143+
TranslatedTextVarChar = DecodedTextVarBinary;
144+
print_this('TranslatedTextVarChar' : %trim(TranslatedTextVarChar));
145+
146+
return;
147+
```
148+
149+
Spoolfile Output:
150+
151+
``` text
152+
Field Name Value
153+
--------------------- --------------------------------------------------------
154+
PlainText MyText
155+
EncodedText TXlUZXh0
156+
DecodedTextVarBinary (`èÁÌÈ
157+
TranslatedTextVarChar MyText
158+
```
159+
160+
In the code above, we first define a field of type `sqltype(VARBINARY:100)` to recieve the decoded text. We define another field of type `VARCHAR(100) CCSID(1208)` which allows us to translate the binary ebcdic data back to UTF-8 text. Unfortunately I haven't found a way to do this in one step. If you know of a better way, please mention it in the comments below.
161+
162+
In summary, while care must be given when defining fields with the correct CCSID values and field types, the IBM i operating system does give us the features we need to encode and decode in base64 just like the rest of the world.
163+

assets/images/Git_Config.gif

8.32 MB
Loading

assets/images/base64-1.png

67.1 KB
Loading

0 commit comments

Comments
 (0)